美文网首页mysql
mysql数据库设计经验

mysql数据库设计经验

作者: 修行者12138 | 来源:发表于2020-08-17 22:54 被阅读0次

同一个系统不同表的主键类型应该保持一致

假设某个系统不同模块都有上传文件的功能,文件信息表的rela_id字段表示该文件对应的具体业务id(比如制度附件的rela_id为制度的id),如果业务id又有varchar类型又有int类型,rela_id的类型就很难定义

created_user、created_date、updated_user、updated_date等公共字段命名保持统一

同一个系统,created_user、created_date、updated_user、updated_date等公共字段的命名和类型都应该保持一致,这样可以在工具类用反射统一设置bean的属性。
工具类示例如下

    /**
     * 设置属性:createUser, createDate
     *
     * @param obj
     */
    public static void setCreateFields(Object obj) {
        Class<?> clazz = obj.getClass();
        Method setCreateUser = null;;
        Method setCreateDate = null;;
        try {
            setCreateUser = clazz.getMethod("setCreatedUser", String.class);
            setCreateDate = clazz.getMethod("setCreatedDate", Date.class);
        } catch (NoSuchMethodException | SecurityException e) {
            logger.info("反射获取get、set方法失败:", e);
            return;
        }

        try {
            setCreateUser.invoke(obj, getUserAccount());
            setCreateDate.invoke(obj, new Date());
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            logger.info("调用方法get、set方法失败:", e);
        }
    }

同一个系统的表字符集保持一致

不同字符集的列在join时,无法使用索引。
比如select * from table_a a, table_b b where a.column_a = b.column_b,如果column_a和column_b的字符集不同,一个为utf8,一个为utf8mb4,无法使用索引

一个系统搭建时应考虑的公共表

系统配置表

用于控制系统的一些配置项(也可以理解为开关),比如某个任务是否开启,是否隐藏某个按钮,等等。
(也可以用配置中心控制,但是比配置中心灵活,本司的配置中心无法实时修改,如果是数据库控制,可以从管理员界面上修改,实时生效)

操作日志表

用于记录用户的操作日志

外部系统请求日志记录表

用于记录与外部系统的请求日志,方便定位问题(shuai guo)

数据字典表

用于定义系统的数据字典,放到同一张表,方便维护,可以从管理员界面修改,实时生效

UUID与自增主键的选择

使用UUID坏处
1.数据量大时读写性能低于自增主键(容易导致innodb页分裂)
2.占用更多存储空间(innodb一个页16k,如果主键占用空间大,一个页能放的记录数就少,会增加IO次数)

使用UUID好处:
1.入库前就知道id
2.无需考虑唯一性问题,但由于性能问题,只适合用于小规模的分布式环境
3.没有规律,安全性高

使用自增主键坏处:
1.入库前获取id比较麻烦(一般ORM框架会提供把id注入bean属性的语法,如mybatis)
2.需要考虑唯一性,如果用于分布式系统,需要设置步长(需要预估业务规模,步长要大于未来最大的集群数)
3.有规律,安全性低(比如接口xxx.com/userInfo?id=12345可以获取到数据,那么暴力尝试xxx.com/userInfo?id=1到xxx.com/userInfo?id=1000000就可能获取到其他数据)

使用自增主键好处:
1.读写性能高
2.占用存储空间小

综上,UUID和自增主键各有利弊,其实除了这两种,还可以选择twitter的snowflake(雪花算法)来生成全局自增主键,同时具备存储空间小,性能高,适用于大规模分布式环境等优点。

中间表

如果需要把其他系统的数据同步到自己的数据库,最好建一张中间表存同步过来的原始数据,而不是直接同步到自己的数据库,原因如下
1.把原始数据落库,方便追溯问题(出了bug,追踪是原始数据的问题还是处理数据出了问题)
2.在中间表加一个字段,标识是否成功同步到自己的数据库,如果失败,用定时任务重试

字段尽量不允许为空

如果字段允许为null,可能会出现诸多问题。
mysql中,null与任何字段(包括自己本身)比较(=或者!=),结果都是false。
例如,想要查出学生中成绩等级不为A的所有学生,select * from student where grade != 'A'这样的sql,无法查出grade为null的记录,也就是查出的结果比预期的要少。
另外,使用not in时,也可能因为null值丢失数据

设计表时考虑好索引和字段

如果某个表有未提交的事务,此时执行alter语句,会触发MDL(metadata lock,元数据锁),因此设计表时,就要考虑好索引和字段,避免在后期执行alter

不要在同一事务中混合使用事务型和非事务型的表(比如混用innodb和myisam),因为非事务型的表无法回滚

相关文章

网友评论

    本文标题:mysql数据库设计经验

    本文链接:https://www.haomeiwen.com/subject/ybbkjktx.html