MySQL例子
MySQL例子
配置MySQL 字符集
修改字符集,配置在my.ini
:
--在 [mysqld] 标签下加上以下内容: default-character-set = utf8 character_set_server = utf8 -- 注意:如果此标签下已经存在“default-character-set=GBK”类似的内容,只需修改即可。 --在 [mysql] 标签下加上一行 default-character-set = utf8 --在 [mysql.server]标签下加上一行 default-character-set = utf8 --在 [mysqld_safe]标签下加上一行 default-character-set = utf8 --在 [client]标签下加上一行 default-character-set = utf8
重启mysql服务,然后检查:
mysql> show variables like 'char%'; show variables like 'collation%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 8 rows in set (0.00 sec) +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | utf8_general_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec) mysql>
删除重复的数据
/* 删除重复的数据,只保留id最小的 */ SELECT `t1`.* FROM `t1`,( SELECT DISTINCT MIN(`id`) AS `id`,`name`,`add` FROM `t1` GROUP BY `name`,`add` HAVING COUNT(1) > 1 ) AS `t2` WHERE `t1`.`name` = `t2`.`name` AND `t1`.`add` = `t2`.`add` AND `t1`.`id` <> `t2`.`id`; +----+------+-----+ | id | name | add | +----+------+-----+ | 2 | abc | 123 | | 4 | abc | 123 | | 7 | xzy | 456 | | 8 | xzy | 456 | | 11 | xzy | 789 | | 13 | ijk | 147 | | 20 | tpk | 963 | | 22 | wer | 546 | +----+------+-----+
修改数据库字符集
修改数据库字符集:
ALTER DATABASE db_name DEFAULT CHARACTER SET character_name [COLLATE ...];
把表默认的字符集和所有字符列(CHAR
,VARCHAR
,TEXT
)改为新的字符集:
ALTER TABLE tbl_name CONVERT TO CHARACTER SET character_name [COLLATE ...]
如:
ALTER TABLE tbl_name DEFAULT CHARACTER SET character_name [COLLATE...];
ALTER TABLE logtest DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
修改字段的字符集:
ALTER TABLE tbl_name CHANGE c_name c_name CHARACTER SET character_name [COLLATE ...];
如:
ALTER TABLE logtest CHANGE title title VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE continent continent VARCHAR(50) CHARACTER SET = utf8mb4 ; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE country country VARCHAR(50) CHARACTER SET = utf8mb4 ; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE countryurl countryurl VARCHAR(50) CHARACTER SET = utf8mb4 ; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE city city VARCHAR(50) CHARACTER SET = utf8mb4 ; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE city city VARCHAR(50) CHARACTER SET = utf8mb4 ; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE city city VARCHAR(50) CHARACTER SET = utf8mb4 ; ALTER TABLE `htlvendorpricemdb`.`agoda_citylist_intl` CHANGE city city VARCHAR(50) CHARACTER SET = utf8mb4 ;
# 查看数据库编码: SHOW CREATE DATABASE db_name; # 查看表编码: SHOW CREATE TABLE tbl_name; # 查看字段编码: SHOW FULL COLUMNS FROM tbl_name;
日期时间
mysql中创建时间和更新时间的区别 原创
`create_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
基本设计原则
自增UUID
UUID 也可以当主键,自增 UUID 比自增主键性能更好,多占用的空间也可忽略不计
MySQL8check函数约束
对于固定选项值的字段,MySQL8 以前推荐使用枚举字段,MySQL8 以后使用check函数约束,不要使用 0,1,2 表示
tinyint的缺点:
- 表达不清:这个表可能是其他同事设计的,你印象不是特别深的话,每次都需要去看字段注释,甚至有时候在编码的时候需要去数据库确认字段含义
- 脏数据:虽然在应用层可以通过代码限制插入的数值,但是还是可以通过sql和可视化工具修改值
MySQL 8以前推荐使用ENUM
枚举字符串类型,外加SQL_MODE
的严格模式。
在MySQL 8.0.16 以后的版本,可以直接使用check约束机制,不需要使用enum枚举字段类型
表的索引个数可以超过5
一张表的索引个数并没有限制不能超过5个,可以根据业务情况添加和删除
MySQL8对子查询优化
MySQL8 对子查询有了优化,可以放心使用。
老版本的 MySQL 数据库对子查询优化有限,所以很多 OLTP 业务场合下,我们都要求在线业务尽可能不用子查询。
然而,MySQL 8.0 版本中,子查询的优化得到大幅提升,所以在新版本的MySQL中可以放心的使用子查询。
子查询相比 JOIN 更易于人类理解,比如我们现在想查看2020年没有发过文章的同学的数量
SELECT COUNT(*) FROM user WHERE id not in ( SELECT user_id from blog where publish_time >= "2020-01-01" AND publish_time <= "2020-12-31" )
可以看到,子查询的逻辑非常清晰:通过 not IN 查询文章表的用户有哪些。
如果用left join
写
SELECT count(*) FROM user LEFT JOIN blog ON user.id = blog.user_id and blog.publish_time >= "2020-01-01" and blog.publish_time <= "2020-12-31" where blog.user_id is NULL;
可以发现,虽然 LEFT JOIN 也能完成上述需求,但不容易理解。
我们使用 explain查看两条 sql 的执行计划,发现都是一样的,
不论是子查询还是 LEFT JOIN,最终都被转换成了left hash Join
,
所以上述两条 SQL 的执行时间是一样的。
即,在 MySQL 8.0 中,优化器会自动地将 IN 子查询优化,
优化为最佳的 JOIN 执行计划,这样一来,会显著的提升性能。