dedecms调取友情链接 网站类型,猎头公司是干什么的,wordpress无法修改主页,重庆网站优化建设大家好#xff0c;我是捡田螺的小男孩。
昨天一位粉丝#xff0c;咨询了一个并发的问题~ 我提供了一个乐观锁兜底的方案#xff0c;然后发现他们的表#xff0c;都没有加version字段的,我想到#xff0c;这不是表设计通用字段嘛。因此#xff0c;本文跟大家聊聊#xf…大家好我是捡田螺的小男孩。
昨天一位粉丝咨询了一个并发的问题~ 我提供了一个乐观锁兜底的方案然后发现他们的表都没有加version字段的,我想到这不是表设计通用字段嘛。因此本文跟大家聊聊设计表的时候有哪些经验准则。
公众号捡田螺的小男孩
设计表时尽量都有这几个通用字段 表必备一般来说或具备这几个字段
id主键一个表必须得有主键必须 create_time创建时间必须 modifed_time: 修改时间必须更新记录时就更新它。 version : 数据记录的版本号一般用于乐观锁非必须 modifier :修改人非必须 creator 创建人非必须 图片
每个字段都要有注释尤其涉及枚举这些时 我们在设计表的时候每个字段都要写上注释哈尤其涉及到一个枚举字段的时候更要把每个枚举值写出来后面如果有变更也要维护到这里来~
反例
CREATE TABLE order_tab ( id INT AUTO_INCREMENT PRIMARY KEY, order_id BIGINT UNIQUE, user_id BIGINT NOT NULL, total_amount DECIMAL(10, 2) NOT NULL, status VARCHAR(20) NOT NULL DEFAULT ‘PENDING’, payment_status VARCHAR(20) DEFAULT ‘not_paid’, version INT DEFAULT 0, created_time DATETIME, updated_time DATETIME, creator VARCHAR(255), modifier VARCHAR(255) ); 正例
CREATE TABLE order_tab ( id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT ‘订单项的唯一标识符自增主键’, order_id BIGINT UNIQUE COMMENT ‘订单的唯一标识符在整个系统中唯一’, user_id BIGINT NOT NULL COMMENT ‘用户的唯一标识符关联到用户表’, total_amount DECIMAL(10, 2) NOT NULL COMMENT ‘订单的总金额精确到小数点后两位’, status VARCHAR(20) NOT NULL DEFAULT ‘PENDING’ COMMENT ‘订单的状态例如PENDING待处理、COMPLETED已完成等’, payment_status VARCHAR(20) DEFAULT ‘not_paid’ COMMENT ‘订单的支付状态如not_paid未支付、paid已支付等’, version INT DEFAULT 0 COMMENT ‘乐观锁版本号用于并发控制’, created_time DATETIME COMMENT ‘订单的创建时间’, updated_time DATETIME COMMENT ‘订单的最后一次更新时间’, creator VARCHAR(255) COMMENT ‘订单的创建者通常记录创建订单的用户或系统的用户名’, modifier VARCHAR(255) COMMENT ‘订单的修改者通常记录最后修改订单的用户或系统的用户名’ ); 3. 命名规范 数据库表名、字段名、索引名等都需要命名规范可读性高(一般要求用英文)让别人一看命名就知道这个字段表示什么意思。
比如一个表的账号字段反例如下
acc_no,1_acc_no,zhanghao 正例
account_no,account_number 表名、字段名必须使用小写字母或者数字禁止使用数字开头禁止使用拼音并且一般不使用英文缩写。 主键索引名为pk_字段名唯一索引名为uk_字段名普通索引名则为idx_字段名。 4. 选择合适的字段类型 设计表时我们需要选择合适的字段类型比如
尽可能选择存储空间小的字段类型就好像数字类型的从tinyint、smallint、int、bigint从左往右开始选择 小数类型如金额则选择 decimal禁止使用 float 和 double。 如果存储的字符串长度几乎相等使用 char 定长字符串类型。 varchar是可变长字符串不预先分配存储空间长度不要超过5000。 如果存储的值太大建议字段类型修改为text同时抽出单独一张表用主键与之对应。 同一表中所有varchar字段的长度加起来不能大于65535. 如果有这样的需求请使用TEXT/LONGTEXT 类型。 5. 主键设计要合理 主键设计的话最好不要与业务逻辑有所关联。有些业务上的字段比如身份证虽然是唯一的一些开发者喜欢用它来做主键但是不是很建议哈。主键最 好是毫无意义的一串独立不重复的数字比如UUID又或者Auto_increment自增的主键或者是雪花算法生成的主键等等;
图片
6.选择合适的字段长度 先问大家一个问题大家知道数据库字段长度表示字符长度还是字节长度嘛
其实在mysql中varchar和char类型表示字符长度而其他类型表示的长度都表示字节长度。比如char(10)表示字符长度是10 而bigint4表示显示长度是4个字节但是因为bigint实际长度是8个字节所以bigint4的实际长度就是8个字节。
我们在设计表的时候需要充分考虑一个字段的长度比如一个用户名字段它的长度5~20个字符你觉得应该设置多长呢可以考虑设置为 username varchar32。字段长度一般设置为2的幂哈也就是2的n次方。
优先考虑逻辑删除而不是物理删除 什么是物理删除什么是逻辑删除
物理删除把数据从硬盘中删除可释放存储空间 逻辑删除给数据添加一个字段比如is_deleted以标记该数据已经逻辑删除。 物理删除就是执行delete语句如删除account_no ‘666’的账户信息SQL如下
delete from account_info_tab whereaccount_no ‘666’; 逻辑删除呢就是这样
update account_info_tab set is_deleted 1 where account_no ‘666’; 为什么推荐用逻辑删除不推荐物理删除呢
为什么不推荐使用物理删除因为恢复数据很困难 物理删除会使自增主键不再连续 核心业务表 的数据不建议做物理删除只适合做状态变更。 8. 一张表的字段不宜过多 我们建表的时候要牢记一张表的字段不宜过多哈一般尽量不要超过20个字段哈。笔者记得上个公司有伙伴设计开户表加了五十多个字段。。。
如果一张表的字段过多表中保存的数据可能就会很大查询效率就会很低。因此一张表不要设计太多字段哈如果业务需求实在需要很多字段可以把一张大的表拆成多张小的表它们的主键相同即可。
当表的字段数非常多时可以将表分成两张表一张作为条件查询表一张作为详细内容表 (主要是为了性能考虑)。
尽可能使用not null定义字段 如果没有特殊的理由 一般都建议将字段定义为 NOT NULL 。
为什么呢
首先 NOT NULL 可以防止出现空指针问题。 其次NULL值存储也需要额外的空间的它也会导致比较运算更为复杂使优化器难以优化SQL。 NULL值有可能会导致索引失效 如果将字段默认设置成一个空字符串或常量值并没有什么不同且都不会影响到应用逻辑 那就可以将这个字段设置为NOT NULL。 10. 设计表时评估哪些字段需要加索引 首先评估你的表数据量。如果你的表数据量只有一百几十行就没有必要加索引。否则设计表的时候如果有查询条件的字段一般就需要建立索引。但是索引也不能滥用
索引也不要建得太多一般单表索引个数不要超过5个。因为创建过多的索引会降低写得速度。 区分度不高的字段不能加索引如性别等 索引创建完后还是要注意避免索引失效的情况如使用mysql的内置函数会导致索引失效的 索引过多的话可以通过联合索引的话方式来优化。然后的话索引还有一些规则如覆盖索引最左匹配原则等等。。 假设你新建一张用户表如下
CREATE TABLE user_info_tab ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, age int(11) DEFAULT NULL, name varchar(255) NOT NULL, create_time datetime NOT NULL, modifed_time datetime NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8; 对于这张表很可能会有根据user_id或者name查询用户信息并且user_id是唯一的。因此你是可以给user_id加上唯一索引name加上普通索引。
CREATE TABLE user_info_tab ( id int(11) NOT NULL AUTO_INCREMENT, user_id int(11) NOT NULL, age int(11) DEFAULT NULL, name varchar(255) NOT NULL, create_time datetime NOT NULL, modifed_time datetime NOT NULL, PRIMARY KEY (id), KEY idx_name (name) USING BTREE, UNIQUE KEY un_user_id (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8; 11. 避免使用MySQL保留字 如果库名、表名、字段名等属性含有保留字时SQL语句必须用反引号来引用属性名称这将使得SQL语句书写、SHELL脚本中变量的转义等变得非常复杂。
因此我们一般避免使用MySQL保留字如select、interval、desc等等
一般都选择INNODB存储引擎 建表是需要选择存储引擎的我们一般都选择INNODB存储引擎除非读写比率小于1%, 才考虑使用MyISAM 。
有些小伙伴可能会有疑惑不是还有MEMORY等其他存储引擎吗什么时候使用它呢其实其他存储引擎一般除了都建议在DBA的指导下使用。
我们来复习一下这MySQL这三种存储引擎的对比区别吧
图片
选择合适统一的字符集 数据库库、表、开发程序等都需要统一字符集通常中英文环境用utf8。
MySQL支持的字符集有utf8、utf8mb4、GBK、latin1等。
utf8支持中英文混合场景国际通过3个字节长度 utf8mb4: 完全兼容utf84个字节长度一般存储emoji表情需要用到它。 GBK 支持中文但是不支持国际通用字符集2个字节长度 latin1MySQL默认字符集1个字节长度 14. 时间的类型选择 我们设计表的时候一般都需要加通用时间的字段如create_time、modified_time等等。那对于时间的类型我们该如何选择呢
对于MySQL来说主要有date、datetime、time、timestamp 和 year。
date 表示的日期值, 格式yyyy-mm-dd,范围1000-01-01 到 9999-12-313字节
time 表示的时间值格式 hh:mm:ss范围-838:59:59 到 838:59:593字节
datetime表示的日期时间值格式yyyy-mm-dd hh:mm:ss范围1000-01-01 00:00:00到9999-12-31 23:59:59,8字节跟时区无关
timestamp表示的时间戳值格式为yyyymmddhhmmss范围1970-01-01 00:00:01到2038-01-19 03:14:074字节跟时区有关
year年份值格式为yyyy。范围1901到21551字节 推荐优先使用datetime类型来保存日期和时间因为存储范围更大且跟时区无关。
安全性考虑 数据加密敏感信息如用户密码应进行加密存储。如果是手机号、邮箱这些则建议脱敏