ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## 字段类型 ### 整数类型 `TINYINT、 SMALLINT、 MEDIUMINT、INT、 BIGINT` 属性: `UNSIGNED` 长度:可以为整数类型指定宽度,例如:INT(11)、对大多数应用 是没有意义的,它不会限制值的合法范围,只会影响显示字符的个 数 > int(3) 可以存入值为1234567 ,且不会切断, > 设置长度是为了 如果设置了 `Zerofill` 存入123 会变为 0123, > 所以 int(0) 也是具有意义的 ### 实数类型 `FLOAT、 DOUBLE、 DECIMAL` DECIMAL可存储比 BIGINT还大的整数;可以用于存储精确的小数,相当于存为字符串 FLOAT和 DOUBLE类型支持使用标准的浮点进行近似计算 ### 字符串类型 `VARCHAR、CHAR、TEXT、BLOB` VARCHAR类型用于存储可变长字符串,它比定长类型更节省空间 VARCHAR使用1或2个额外字节记录字符串的长度,列长度小于 255字节,使用1个字节表示,否则用2个 > `char` 定长 ,如 `char(10)` 不管你存入多长, 都占用10 个字节,用于存储定长的字符串 > `varchar` 与 `char` 会切断长度长度的字符串 ,超过255字节的只能用`varchar`或者`text`; > 如果存储值很短或定长,可以选择` char` > 能用`varchar`的地方不用`text`; ### 枚举 `create table user_sex( sex enum('M','F'));` 有时可以使用枚举代替常用的字符串类型 把不重复的集合存储成一个预定义的集合 非常紧凑,把列表值压缩到一个或两个字节 部存储的是整数 ### 日期和时间类型 尽量使用 `TIMESTAMP`,比 `DATETIME`空间效率高 用整数保存时间戳的格式通常不方便处理 如果需要存储微秒,可以使用 bigint存储 ``` date 1000-01-01 ~ 9999-12-31 datetime 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59 timestamp 1970-01-01 00:00:01 ~ 2038-01-19 03:14:07 ``` ## 数据表引擎 ### Innodb表引擎 默认事务型引擎,最重要最广泛的存儲引擎,性能非常优秀 数据存储在共享表空间,可以通过配置分开 对主键查询的性能高于其他类型的存储引擎 内部做了很多优化,从磁盘读取数据时自动在内存构建hash索引 插入数据时自动构建插入缓冲区 通过一些机制和工具支持真正的热备份 支持崩溃后的安全恢复 支持行级锁 支持外键 ### MYISAM表引擎 51版本前, MYISAM是默认的存储引擎 拥有全文索引l、压缩、空间函数 表锁,不支持事务和行级锁,不支持崩溃后的安全恢复 表存储在两个文件,MYD和MYI 设计简单,某些场景下性能很好 ### 其他表引擎 Archive、 Blackhole、csV、 Memory ## 锁机制 表锁是日常开发当中常见的问题,当多个查询同一时刻进行数据修改时,就会产生并发控制的问题 ### 共享锁(读锁)和排他锁(写锁) #### 读锁 共享的,不堵塞,多个用户可以同时读一个资源,互不干扰 #### 写锁 排他的,一个写锁会阻塞其他的写锁和读锁,这样可以只允许一人进行写入,防止其他用户读取正在写入的资源。 ### 锁粒度 - 表锁,系统性能开销最小,会锁定整张表, MYISAM使用表锁 - 行锁,最大程度地支持并发处理,但是也带来了最大的锁开销,Innodb实现行级锁 ## 事务处理 MYSQL提供事务处理的表引|擎, Inno DB 服务器层不管理事务,由下层的引擎实现,所以同一个事务中,使 用多种存储引擎不靠谱 在非事务的表上执行事务操作 MYSQL不会发出提醒,也不会报错 ## 存储过程 为以后的使用而保存的一条或多条 MYSQL语句的集合 存储过程就是有业务逻辑和流程的集合 可以在存储过程中创建表,更新数据,删除等等 ## 触发器 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与 表事件相关的特殊的存储过程 ### 使用场景 可通过数据库中的相关表实现级联更改 实时监控某张表中的某个字段的更改而需要做出相应的处理 某些业务编号的生成等 滥用会造成数据库及应用程序的维护困难 > [MySQL 视图、函数、存储过程和触发器 简书 详解](https://www.jianshu.com/p/814d8aee700a) ## 索引的基础和类型 ### 索引对性能的影响 大大减少服务器需要扫描的数据量 帮助服务器避免排序和临时表 将随机I/O变顺序I/O 大大提高查询速度,降低写的速度、占用磁盘 ### 索引的使用场景 对于非常小的表,大部分情况下全表扫描效率更高 特大型的表,建立和使用索引的代价将随之增长,可以使用分区技术来解决 ### 索引的类型 索引|有很多种类型,都是实现在存储引擎层的 - 普通索引:最基本的索引,没有任何约束限制 - 唯一索引:与普通索引类似,但是具有唯一性约束 - 主键索引:主键可以与外键构成参照完整性约束,防止数据不一致 - 组合索引:将多个列组合在一起创建索引,可以覆盖多个列 - 外键索引:只有 Innodb类型的表才可以使用外键索引,保证数据的一致性、完整性和实现级联操作 - 全文索引: MYSQL自带的全文索引只能用于 MYISAM,并且只能对英文进行全文检索 ### 创建索引的原则 1. 最适合索引的列是出现在 WHERE子句中的列,或连接子句中的列而不是出现在 SELECT关键字后的列 2. 索引列的基数越大,索引的效果越好 3. 对字符串进行索引,应该制定一个前缀长度,可以节省大量的索引空间 4. 根据情况创建复合索引,复合索引可以提高查询效率 5. 避免创建过多索引,索引|会额外占用磁盘空间,降低写操作效率 6. 主键尽可能选择较短的数据类型,可以有效减少索引的磁盘占用提高查询效率 ### 索引的注意事项 1. 复合索引遵循前缀原则 ``` 创建的索引有顺序,非顺序的索引不生效 KEY(a, b, c) //创建 a b c 索引 WHERE a=l and b=2 and c= 3 //生效 WHERE a=1 and b=2 //生效 WHERE a= 1 //生效 WHERE b=2 andc= 3 //无效 WHERE a= 1 and c=3 //无效 ``` 2. like查询,%在前,则素以失效,可以使用全文索引 3. column is null可以使用索引 `where name=null //也是可以使用索引` 4. 如果 MYSQL估计使用索引比全表扫描更慢,会放弃使用索引 `如果只有100 条数据 where id 1>and id<100 会自动转为全表索引` 5. 如果or前的条件中的列有索引,后面的没有,索引都不会被用到 `where name='cpj' or age='12'` 7. 列类型是字符串,查询时一定要给值加引|号,否则索引失效 ``` name varchar(16) 存了 "100" Where name =100 //虽然能得到值 但是没有使用索引 ``` ## 六种关联查询 ### 交叉连接 CROSS JOIN ``` SELECT* FROM A,B(C)或者 SELECT* FROM A CROSS JOIN B(CROSS JOIN C //没有任何关联条件,结果是笛卡尔积,结果集会很大,没有意义,很少使用 ``` ### 内连接 INNER JOIN ``` SELECT* FROM A, B WHERE A id=Bd或者 SELECT FROM A INNER JOIN B ON A.id=Bid ``` #### 内连接分为三类 - 等值连接: ON Aid=Bid - 不等值连接: ON A id>B.d - 自连接: `SELECT* FROM A T1 INNER JOIN A T2 on T1.id=T2. pid` - ### 外连接 LEFT JOIN/ RIGHT JOIN #### 左外连接 LEFT OUTER JOIN,以左表为主,先查询出左表,按照ON后的关联条件匹配右表,没有匹配到的用NULL填充,可以简写成 LEFT JOIN #### 右外连接 RIGHT OUTER JOIN,以右表为主,先查询出右表,按照ON后的关联条件匹配左表,没有匹配到的用NULL填充,可以简写成 RIGHT JOIN ### 联合查询 UNION与 UNION ALL `SELECT* FROM A UNION SELECT* FROM B UNION··` 就是把多个结果集集中在一起, UNION前的结果为基准,需要注 意的是联合查询的列数要相等,相同的记录行会合并 UNION ALL不会合并重复的结果集 ### 嵌套语句 用一条SQL语句的结果作为另外一条SQL语句的条件 `SELECT FROM A WHERE id IN(SELECT id FROM B)` ## 真题 1. 更新 b 表 的 c1 c2 到 A 表的 c1 c2 ``` A(id, sex, par, cl, c2) B(id, age, cl, c2) //方法一 update a, b set A.cl= B.cl, A.c2=B.c2 where A.id = B.id and B.age >50 //方法二 update a inner join B on Aid B id set A.c1=B.c1,A.c2= B.c2 where Bage >50 ```