精华内容
下载资源
问答
  • 工作流数据库表结构设计

    热门讨论 2014-04-26 10:31:50
    工作流就是业务流程的计算机化或自动化。许多公司采用纸张表单,手工传递的方式,一级一级审批签字,工作效率非常低下,对于统计报表功能则不能实现。...:::本资源包含了工作流所涉及的表结构设计。:::
  • 数据库表结构设计

    千次阅读 2019-04-08 21:20:30
    在进行数据库的表结构设计的实操之前,应当好好了解一下数据库表结构设计的几个关键的问题: 为什么要学习数据库表结构设计 在实际的数据库开发中,需要将大量的结构化数据汇总到数据库表中,这时候不能鲁莽的开始...

    在进行数据库的表结构设计的实操之前,应当好好了解一下数据库表结构设计的几个关键的问题:

    为什么要学习数据库表结构设计

    在实际的数据库开发中,需要将大量的结构化数据汇总到数据库表中,这时候不能鲁莽的开始设计单个数据库表,应当考虑几个问题:表名称如何命名,表中有哪些字段,各个字段的命名规范,字段的数据类型,字段的长度以及和其他的表之间的关联等。

    数据库表结构的设计原则

    数据库设计的三大范式,范式即关系型数据库中所要遵循的规则。

    1. 第一范式
      每一列的属性都是不可再分的属性值,确保每一列的原子性;
      两列的属性相近或相似或一样,尽量合并属性一样的列,确保不产生冗余数据。

    2. 第二范式
      保证数据库中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言),即一行数据只做一件事。也就是说,在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中;

    3. 第三范式
      需要确保数据库表中每一列的数据都和主键直接相关,不能间接相关,像属性之间有这样的关系:a->b->c是不符合第三范式的。

    数据库表结构设计时应当注意的一些事项

    • 不应该针对整个系统进行数据库的设计,首先应当根据系统架构中的组件进行划分,针对每个组件所处的业务进行组件单元的数据库设计;不同组件之间对应的数据库表之间的关联应当尽可能减少,如果不同组件间的表需要外键关联,也尽量不要创建外键关联,而只是记录关联表的一个主键,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。

    • 应当采用领域模式驱动的方式和自顶向下的思路进行数据库设计,首先要分析系统业务,根据职责定义对象。对象要符合封装的特性,确保与职责相关的数据项被定义在一个对象之内,这些数据项要能够完整的描述该职责,不会出现职责的缺失。并且一个对象有且只有一项职责,如果一个对象要负责两个或两个以上的职责,应进行分拆。

    • 一个表中的所有的非关键字属性都依赖于整个关键字,关键字可以是一个属性,也可以是多个属性的集合。不论哪种方式,都应当确保关键字的唯一性。在确定关键字时,应该保证关键字不会参与业务,并且不会出现更新异常,最优的解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字。

    • 领域模型中的每一个对象只有一项职责,所以对象中的数据项不存在依赖传递(第三范式)。

    • 由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系,所以在领域模型中的对象存在主对象和从对象之分,从对象是从1-N或N-N的角度进一步完善主对象的业务逻辑,所以表以及表的关联关系不应该出现删除和插入异常。

    • 在映射后得出的数据库表结构中,应当再根据第四范式进行进一步修改,确保不存在多值依赖。

    • 表和表之间的关联应当尽量采用弱关联以便于对表字段和表结构的调整和重构。并且,数据库中的表示用来持久化一个对象实例在特定时间、特定条件下的状态的,只是一个存储介质,所以表和表之间也不应该用强关联来表述业务(数据间的一致性),这一职责应由系统的逻辑层来保证,这种方式也确保了系统对于不正确数据(脏数据)的兼容性。

    • 应针对所有表的主键和外键建立索引,有针对性的简历组合属性的索引,提高检索效率。

    • 尽量少采用存储过程,目前已经有很多技术可以代替存储过程的功能,例如“对象/关系映射”等

    • 当处理表间的关联约束所付出的代价超过了保证不会出现修改、删除、更改异常所付出的代价,并且数据冗余也不是主要的问题时,表设计可以不符合四个范式。四个凡是确保了不会出现异常,但也可能导致过于纯洁的设计,使得表结构难于使用。

    • 设计出的表要具有较好的实用性,主要体现在查询时是否需要关联多张表,并且还需要使用复杂的SQL技巧。

    表设计约定规则

    • 表必须要有主键

    • 一个字段只表示一个含义

    • 总是包含两个日期字段:gmt_create(创建日期),gmt_modified(修改日期),且这两个字段不应该包含有额外的业务逻辑。MySQL中,gmt_create、gmt_modified使用DATETIME类型。

    • 禁止使用复杂数据类型(数组,自定义类型等)。

    • MySQL中,附属表拆分后,附属表id与主表id保持一致。不允许在附属表新增主键字段。

    • MySQL中,存在过期概念的表,在其设计之初就必须有过期机制,且有明确的过期时间。过期数据必须迁移至历史表中。

    • MySQL中,不再使用的表,必须通知DBA予以更名归档。

    • MySQL中,线上表中若有不再使用的字段,为保证数据完整,禁止删除。

    • MySQL中,禁止使用OCI驱动,全部使用THI驱动。

    展开全文
  • 数据库表结构设计方法及原则

    万次阅读 2017-03-23 08:50:27
     数据库设计的三大范式:为了建立冗余较小、结构合理的数据库设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须...
     
    

      数据库设计的三大范式:为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。

      在实际开发中最为常见的设计范式有三个:第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式;第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中;第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。总结一下,就是:第一范式(确保每列保持原子性);第二范式(确保表中的每列都和主键相关);第三范式(确保每列都和主键列直接相关,而不是间接相关)。

      在目前的企业信息系统中,数据库还是最佳的数据存储方式,虽然已经有很多的书籍在指导我们进行数据库设计,但应该那种方式是设计数据库的表结构的最好方法、设计时应遵从什么样的原则、四个范式如何能够用一种方式达到顺畅的应用等是我一直在思考和总结的问题,下文是我针对这几个问题根据自己的设计经历准备总结的一篇文章的提纲,欢迎大家一块进行探讨,集思广益。其中提到了领域建模的概念,但未作详细解释,希望以后能够有时间我们针对这个命题进行深入探讨。

      1.不应该针对整个系统进行数据库设计,而应该根据系统架构中的组件划分,针对每个组件所处理的业务进行组件单元的数据库设计;不同组件间所对应的数据库表之间的关联应尽可能减少,如果不同组件间的表需要外键关联也尽量不要创建外键关联,而只是记录关联表的一个主键,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。

    //注意他这里说的是"不要创建外键关联",创建外键关联的语句是:
    //foreign key(member_id) references member (id);
    //我们几乎没有用到这条语句,因为我们就是这样做的,用到外键时,只是记录关联表的主键,而非在数据库级别上创建外键。
    //也不知道是歪打正着,还是前辈DBA过于强大,已经考虑好了。

      2.采用领域模型驱动的方式和自顶向下的思路进行数据库设计,首先分析系统业务,根据职责定义对象。对象要符合封装的特性,确保与职责相关的数据项被定义在一个对象之内,这些数据项能够完整描述该职责,不会出现职责描述缺失。并且一个对象有且只有一项职责,如果一个对象要负责两个或两个以上的职责,应进行分拆。

    // 领域模型驱动的方式,目前用的还不是很熟,考虑的不够多。因为经常的数据库中的表只是拿来做存储用而已,
    //特别是小需求,要加什么字段,找到相关表加上去就行了,不太考虑领域模型。这个在中文站老业务表里很常见

      3.根据建立的领域模型进行数据库表的映射,此时应参考数据库设计第二范式:一个表中的所有非关键字属性都依赖于整个关键字。关键字可以是一个属性,也可以是多个属性的集合,不论那种方式,都应确保关键字能够保证唯一性。在确定关键字时,应保证关键字不会参与业务且不会出现更新异常,这时,最优解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字。

      4.由于第一点所述的领域模型驱动的方式设计数据库表结构,领域模型中的每一个对象只有一项职责,所以对象中的数据项不存在传递依赖,所以,这种思路的数据库表结构设计从一开始即满足第三范式:一个表应满足第二范式,且属性间不存在传递依赖。

    //数据库三范式记不得的同学去查资料温习一下。
    //个人认为第三范式的目的是尽量减少数据冗余,保证相同的数据只存在一份。
    //第三范式其实我们遵守的并不是很严格,特别是老的数据库表中会有冗余字段。这个要看情况决定吧。

      5.同样,由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系,所以在领域模型中的对象存在主对象和从对象之分,从对象是从1-N或N-N的角度进一步完善主对象的业务逻辑,所以从对象及对象关系映射为的表及表关联关系不存在删除和插入异常。

    //最后一句看不懂,可能是"所以表及表关联关系不应该出现删除和插入异常。"?

      6.在映射后得出的数据库表结构中,应再根据第四范式进行进一步修改,确保不存在多值依赖。这时,应根据反向工程的思路反馈给领域模型。如果表结构中存在多值依赖,则证明领域模型中的对象具有至少两个以上的职责,应根据第一条进行设计修正。第四范式:一个表如果满足BCNF,不应存在多值依赖。 

    复制代码
    //第四范式我们遵守的并不多吧。
    //例如:
    //VAS_WP_CONFIG.config_name字段的值包括:adv(广告主题)/glare(炫彩滚动主题)/theme_simple(普通主题)/theme_cartoon(动画主题)/ theme_none(不显示背景主题)
    //cate_background(类目背景)/video(公司视频)/board_cartoon(动画招牌)/board_simple(普通招牌)等。
    //如果遵守第四范式,则需要新增一张VAS_WP_CONFIG_NAME表,存储配置名称枚举值,而VAS_WP_CONFIG.config_name字段改为VAS_WP_CONFIG.config_name_id。
    //这样做更利于扩展,不会因为每个人的理解不一致而向VAS_WP_CONFIG.config_name字段里设置乱七八糟的值,但是这样需要维护更多的小表,造成数据值表的数量膨胀,DBA可能会觉得管理上有更多的困难。
    //我们采用潜规则约定、java枚举类等其它方式来进行保证。但有时候效果并不是很好,经常发现旧数据库表中枚举字段的值五花八门,不全是约定的。
    复制代码

      7.在经过分析后确认所有的表都满足二、三、四范式的情况下,表和表之间的关联尽量采用弱关联以便于对表字段和表结构的调整和重构。并且,我认为数据库中的表是用来持久化一个对象实例在特定时间及特定条件下的状态的,只是一个存储介质,所以,表和表之间也不应用强关联来表述业务(数据间的一致性),这一职责应由系统的逻辑层来保证,这种方式也确保了系统对于不正确数据(脏数据)的兼容性。当然,从整个系统的角度来说我们还是要尽最大努力确保系统不会产生脏数据,单从另一个角度来说,脏数据的产生在一定程度上也是不可避免的,我们也要保证系统对这种情况的容错性。这是一个折中的方案。

      8.应针对所有表的主键和外键建立索引,有针对性的(针对一些大数据量和常用检索方式)建立组合属性的索引,提高检索效率。虽然建立索引会消耗部分系统资源,但比较起在检索时搜索整张表中的数据尤其时表中的数据量较大时所带来的性能影响,以及无索引时的排序操作所带来的性能影响,这种方式仍然是值得提倡的。

    //索引目前都是DBA根据具体的SQL来创建的,不过开发写SQL时,也应该适当考虑一下字段的索引。

      9.尽量少采用存储过程,目前已经有很多技术可以替代存储过程的功能如"对象/关系映射"等,将数据一致性的保证放在数据库中,无论对于版本控制、开发和部署、以及数据库的迁移都会带来很大的影响。但不可否认,存储过程具有性能上的优势,所以,当系统可使用的硬件不会得到提升而性能又是非常重要的质量属性时,可经过平衡考虑选用存储过程。

    //目前都是杜绝使用存储过程的,我觉得用起来比较方便,对于我们来说,主要原因是会给DBA带来管理方面的麻烦,
    //因为时间一长,存储过程的逻辑和使用场景,往往没人能了解,容易产生更多问题

      10.当处理表间的关联约束所付出的代价(常常是使用性上的代价)超过了保证不会出现修改、删除、更改异常所付出的代价,并且数据冗余也不是主要的问题时,表设计可以不符合四个范式。四个范式确保了不会出现异常,但也可能由此导致过于纯洁的设计,使得表结构难于使用,所以在设计时需要进行综合判断,但首先确保符合四个范式,然后再进行精化修正是刚刚进入数据库设计领域时可以采用的最好办法。

      11.设计出的表要具有较好的使用性,主要体现在查询时是否需要关联多张表且还需使用复杂的SQL技巧。我感觉遵守的范式越多,就越使SQL复杂,具体情况具体分析。设计出的表要尽可能减少数据冗余,确保数据的准确性,有效的控制冗余有助于提高数据库的性能

      因此,考虑了以上条件之后,表设计约定规则如下:

    复制代码
    //规则1:表必须要有主键。
    //规则2:一个字段只表示一个含义。
    //规则3:总是包含两个日期字段:gmt_create(创建日期),gmt_modified(修改日期),且这两个字段不应该包含有额外的业务逻辑。
    //规则4:MySQL中,gmt_create、gmt_modified使用DATETIME类型。
    //规则5:禁止使用复杂数据类型(数组,自定义类型等)。
    //规则6: MySQL中,附属表拆分后,附属表id与主表id保持一致。不允许在附属表新增主键字段。
    //规则7: MySQL中,存在过期概念的表,在其设计之初就必须有过期机制,且有明确的过期时间。过期数据必须迁移至历史表中。
    //规则8: MySQL中,不再使用的表,必须通知DBA予以更名归档。
    //规则9: MySQL中,线上表中若有不再使用的字段,为保证数据完整,禁止删除。
    //规则10: MySQL中,禁止使用OCI驱动,全部使用THI驱动。
    复制代码

    关于MySQL的部分学习笔记总结:

    一、事务跟存储引擎

      1.四种事务隔离级别:read uncommited, read commited(大多数db默认的),repeatable read(mysql默认), seriazable。

      2.mysql是默认的auto commited, 也就是说每次查询默认都是自动提交的(show variables like 'autocommited')。mysql可以通过set transaction isolatioin level命令来设置隔离级别,例如:set session transaction isolation level read commited。

      3.mysql中像innodb采用mvcc(多版本并发控制)来处理并发。mvcc只工作在read commited,repeatable read这两种事务隔离级别上。read uncommited隔离级别不兼容mvcc是因为在该级别得下的查询,不读取符合当前事务版本的数据行,而是最新版本的数据行。seriazable隔离级别不兼容MVCC,因为该级别下的读操作会对每个返回行进行加锁。

      4.选择存储引擎,并发选用myisam,事务选择innodb,myisam比innodb更容易出错,出错了恢复的时间也比较长。只有myisam支持全文检索。

      5.把表从一种存储引擎转到另一种引擎:

    //  1.    alter table mytable engine=falcon;  操作费时,可能会占用服务器的所有i/o处理能力。
    //  2.    create table innodb_table like myisam_table;
    //        alter table innodb_table engine=innodb;
    //        insert into innodb_table select * from myisam_table;

    二、数据类型

      1.尽可能的要把field定义为Not NULL, mysql比较难优化使用了可空列的查询,它会使索引,索引统计更加复杂。可空列需要更多的存储空间,还需要mysql内部进行特殊处理,当可空列被索引时,每条记录都需要一个格外的字节。 即使要在表中存储"没有值"的字段,考虑使用0,特殊字段或者空字符串来代替。

      2.datetime与timestamp能保存同样的数据:精确度为秒,但是timestamp使用的空间只有datetime的一半,还能保存时区,拥有特殊的自动更新能力。但是timestamp保存的时间范围要比datetime要小得多。mysql能存储的最细的时间粒度为秒

      3.mysql支持很多种别名,如bool,integer,nummeric.

      4.float与double类型支持使用标准的浮点运算进行近似计算。 Decimal类型保存精确的小数,在>=mysql5.0,mysql服务器自身进行了decimal的运算,因为CPU不支持直接对它进行运算,所以慢一点。

      5.mysql会把text与blob类型的列当成有实体的对象来进行保存。他们有各自的数据类型家族(tinytext,smalltext,text,mediumtext,longtext; blob类似); mysql对blob与text列排序方式和其他类型有所不同,它不会按照字符串的完整长度来排序。而只是按照max_sort_length规定的若干个字节来进行排序。

      6.采用enum来代替字符串类型。mysql在内部把每个枚举值都保存为整数。enum在内部是按照数字进行排序的,而不是按照字符串。enum最不好的就是字符串列表是固定的,添加和删除必须使用alter table。

      7.ip地址,一般会采用varchar(15)列来保存。事实上,IP地址是个无符号的32位整数,而不是字符串。mysql提供了inet_aton()和inet_nota()函数在证书与ip地址之间进行转换。

    三、索引

      1.聚集索引不仅仅是一种单独的索引类型,而且是一种存储数据的方式。Innodb引擎的聚集索引实际上在同样的结构中保存了B-Tree索引和数据行。当表有聚集索引时,它的数据行实际上保存在索引的叶子上。注意是存储引擎来实现索引。

      2.myisam与innodb数据布局:myisam索引树(无论是主键索引还是非主键索引)叶子节点都是指向的数据行,而innodb中聚集索引,主键索引树叶子节点就带得有数据的内容,而非主键索引树中叶子节点指向主键值,而不是数据的位置。

      3.mysql有两种产生排序结果的方式:使用文件排序,或者扫描有序的索引。目前只有myisam支持全文索引。

      4.myisam表有表级锁;myisam表不支持事务,实际上,myisam并不保证单条命令完成;myisam只缓存了mysql进程内部的索引,并保存在键缓存区内。OS缓存了表的数据;行被紧密的保存在一起,磁盘上的数据有很小的磁盘占用和快速的全表扫描。

      5.innodb支持事务和四种事务隔离级别;在mysql5.0中,只有innodb支持外鍵;支持行级锁与mvcc;所有的innodb表都是按照主键聚集的;所有索引(出开主键)都是按主键引用行;索引没有使用前缀压缩,因此索引可能比myisam大很多;数据转载缓慢;阻塞auto_increment,也就是用表级锁来产生每个auto_increment。

    四、MYSQL性能分析

      1.mysql提供了一个benchmark(int 循环次数,char* 表达式); 可以分析表达式执行所花时间。 例如:

    // select BENCHMARK(10000,SHA1('aaaaaaaaaaaaaaaa'))

      2.mysql有两种查询日志:普通日志和慢速日志。

    五、MYSQL高级特性

      1.在mysql中,只有myisam存储引擎支持全文索引。myisam全文索引是一种特殊的具有两层结构的B树。

      2.存储引擎事务在存储引擎内部被赋予acid属性,分布式(XA)是一种高层次事务,它可以历哟内部个两段提交的方式将acid属性扩展到存储引擎外部,甚至数据库外部。阶段1:通知所有提交者准备提交 阶段2:通知所有参与者进行真正提交。

      3.mysql 的字符集和校对规则有 4 个级别的默认设置:服务器级、数据库级、表级和字段级。Mysql4.1 开始支持 SQL 的子查询。

    复制代码
    /******************************************/
    /*   数据库全名 = degopen@10.218.249.92:3318【mysql】   */
    /*    表名称 = task_new   */
    /******************************************/
    CREATE TABLE `task_new` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
      `task_name` varchar(128) NOT NULL COMMENT '任务名称',
      `image` varchar(128) DEFAULT NULL COMMENT '任务图标',
      `description` varchar(1024) NOT NULL COMMENT '任务描述',
      `content` varchar(1024) NOT NULL COMMENT '任务内容',
      `finished_message` varchar(128) DEFAULT NULL COMMENT '任务完成提示信息',
      `task_scope` int(11) NOT NULL COMMENT '任务范围, 0-平台任务, 1-游戏任务',
      `series_task` int(11) NOT NULL DEFAULT '0' COMMENT '任务类型: 系列任务,单独任务',
      `task_type` int(11) NOT NULL DEFAULT '0' COMMENT '任务类型: 固定任务, 推广任务, 日常任务',
      `pre_task` varchar(128) DEFAULT NULL COMMENT '前置任务',
      `post_task` varchar(128) DEFAULT NULL COMMENT '后置任务',
      `task_status` int(11) NOT NULL COMMENT '任务状态, 待审核、未开始、生效中、已暂停、已完成、审核未通过',
      `auto_task` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否手动任务, 0-否, 1-是',
      `is_required` tinyint(4) NOT NULL COMMENT '是否必须任务',
      `event_type` varchar(64) DEFAULT NULL COMMENT '关心的事件类型',
      `task_target` bigint(20) DEFAULT '0' COMMENT '任务目标',
      `reset_num` int(11) NOT NULL COMMENT '重置次数',
      `reset_cycle` int(11) NOT NULL COMMENT '重置周期',
      `task_interval` int(11) NOT NULL COMMENT '任务间隔',
      `xiaoer` bigint(20) unsigned NOT NULL COMMENT '创建人',
      `review_id` bigint(20) unsigned NOT NULL COMMENT '审核人ID',
      `last_start_time` datetime DEFAULT NULL COMMENT '上次生效时间',
      `gmt_create` datetime NOT NULL COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL COMMENT '修改时间',
      `start_time` datetime NOT NULL COMMENT '开始时间',
      `end_time` datetime NOT NULL COMMENT '结束时间',
      `start_condition` varchar(1024) NOT NULL COMMENT '任务触发条件',
      `end_condition` varchar(1024) NOT NULL COMMENT '任务完成条件',
      `enable` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否可用',
      `rule` varchar(4096) NOT NULL COMMENT '任务规则',
      `priority` int(11) NOT NULL DEFAULT '1' COMMENT '任务优先级',
      `progress_rule` varchar(2048) NOT NULL DEFAULT '' COMMENT '进度计算规则',
      `order_no` int(11) DEFAULT '1' COMMENT '排序号',
      `classification` int(11) DEFAULT '0' COMMENT '0:默认分类\n1:玩游戏\n2:抽奖',
      `level` int(11) DEFAULT '0' COMMENT '针对同一个分类,不同的等级',
      `ext1` longtext COMMENT '扩展字段1(UU中使用该字段指示按钮跳转)',
      `ext2` longtext COMMENT '扩展字段2,暂时预留',
      `channel` int(11) DEFAULT '0' COMMENT '任务渠道:0-uu或者1-game_box',
      `consecutive_day` int(11) DEFAULT '1' COMMENT '连续完成任务的天数',
      `activity` varchar(256) DEFAULT 'default' COMMENT '任务所属的活动名字',
      `device` text COMMENT '机型',
      `packages` text COMMENT '应用',
      PRIMARY KEY (`id`),
      KEY `name_channel` (`task_name`,`channel`),
      KEY `activity` (`activity`(255))
    ) ENGINE=InnoDB AUTO_INCREMENT=1194 DEFAULT CHARSET=utf8 COMMENT='任务表';
    复制代码
    展开全文
  • 数据库表结构设计方法及原则(li)

    千次阅读 2019-09-21 22:45:57
    数据库设计的三大范式:为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。...如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式;第二范式在第一范式的基...

      数据库设计的三大范式:为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库,必须满足一定的范式。

      在实际开发中最为常见的设计范式有三个:第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式;第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中;第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。总结一下,就是:第一范式(确保每列保持原子性);第二范式(确保表中的每列都和主键相关);第三范式(确保每列都和主键列直接相关,而不是间接相关)。

      在目前的企业信息系统中,数据库还是最佳的数据存储方式,虽然已经有很多的书籍在指导我们进行数据库设计,但应该那种方式是设计数据库的表结构的最好方法、设计时应遵从什么样的原则、四个范式如何能够用一种方式达到顺畅的应用等是我一直在思考和总结的问题,下文是我针对这几个问题根据自己的设计经历准备总结的一篇文章的提纲,欢迎大家一块进行探讨,集思广益。其中提到了领域建模的概念,但未作详细解释,希望以后能够有时间我们针对这个命题进行深入探讨。

      1.不应该针对整个系统进行数据库设计,而应该根据系统架构中的组件划分,针对每个组件所处理的业务进行组件单元的数据库设计;不同组件间所对应的数据库表之间的关联应尽可能减少,如果不同组件间的表需要外键关联也尽量不要创建外键关联,而只是记录关联表的一个主键,确保组件对应的表之间的独立性,为系统或表结构的重构提供可能性。

    //注意他这里说的是"不要创建外键关联",创建外键关联的语句是:
    //foreign key(member_id) references member (id);
    //我们几乎没有用到这条语句,因为我们就是这样做的,用到外键时,只是记录关联表的主键,而非在数据库级别上创建外键。
    //也不知道是歪打正着,还是前辈DBA过于强大,已经考虑好了。

      2.采用领域模型驱动的方式和自顶向下的思路进行数据库设计,首先分析系统业务,根据职责定义对象。对象要符合封装的特性,确保与职责相关的数据项被定义在一个对象之内,这些数据项能够完整描述该职责,不会出现职责描述缺失。并且一个对象有且只有一项职责,如果一个对象要负责两个或两个以上的职责,应进行分拆。

    // 领域模型驱动的方式,目前用的还不是很熟,考虑的不够多。因为经常的数据库中的表只是拿来做存储用而已,
    //特别是小需求,要加什么字段,找到相关表加上去就行了,不太考虑领域模型。这个在中文站老业务表里很常见

      3.根据建立的领域模型进行数据库表的映射,此时应参考数据库设计第二范式:一个表中的所有非关键字属性都依赖于整个关键字。关键字可以是一个属性,也可以是多个属性的集合,不论那种方式,都应确保关键字能够保证唯一性。在确定关键字时,应保证关键字不会参与业务且不会出现更新异常,这时,最优解决方案为采用一个自增数值型属性或一个随机字符串作为表的关键字。

      4.由于第一点所述的领域模型驱动的方式设计数据库表结构,领域模型中的每一个对象只有一项职责,所以对象中的数据项不存在传递依赖,所以,这种思路的数据库表结构设计从一开始即满足第三范式:一个表应满足第二范式,且属性间不存在传递依赖。

    //数据库三范式记不得的同学去查资料温习一下。
    //个人认为第三范式的目的是尽量减少数据冗余,保证相同的数据只存在一份。
    //第三范式其实我们遵守的并不是很严格,特别是老的数据库表中会有冗余字段。这个要看情况决定吧。

      5.同样,由于对象职责的单一性以及对象之间的关系反映的是业务逻辑之间的关系,所以在领域模型中的对象存在主对象和从对象之分,从对象是从1-N或N-N的角度进一步完善主对象的业务逻辑,所以从对象及对象关系映射为的表及表关联关系不存在删除和插入异常。

    //最后一句看不懂,可能是"所以表及表关联关系不应该出现删除和插入异常。"?

      6.在映射后得出的数据库表结构中,应再根据第四范式进行进一步修改,确保不存在多值依赖。这时,应根据反向工程的思路反馈给领域模型。如果表结构中存在多值依赖,则证明领域模型中的对象具有至少两个以上的职责,应根据第一条进行设计修正。第四范式:一个表如果满足BCNF,不应存在多值依赖。 

    //第四范式我们遵守的并不多吧。
    //例如:
    //VAS_WP_CONFIG.config_name字段的值包括:adv(广告主题)/glare(炫彩滚动主题)/theme_simple(普通主题)/theme_cartoon(动画主题)/ theme_none(不显示背景主题)
    //cate_background(类目背景)/video(公司视频)/board_cartoon(动画招牌)/board_simple(普通招牌)等。
    //如果遵守第四范式,则需要新增一张VAS_WP_CONFIG_NAME表,存储配置名称枚举值,而VAS_WP_CONFIG.config_name字段改为VAS_WP_CONFIG.config_name_id。
    //这样做更利于扩展,不会因为每个人的理解不一致而向VAS_WP_CONFIG.config_name字段里设置乱七八糟的值,但是这样需要维护更多的小表,造成数据值表的数量膨胀,DBA可能会觉得管理上有更多的困难。
    //我们采用潜规则约定、java枚举类等其它方式来进行保证。但有时候效果并不是很好,经常发现旧数据库表中枚举字段的值五花八门,不全是约定的。

      7.在经过分析后确认所有的表都满足二、三、四范式的情况下,表和表之间的关联尽量采用弱关联以便于对表字段和表结构的调整和重构。并且,我认为数据库中的表是用来持久化一个对象实例在特定时间及特定条件下的状态的,只是一个存储介质,所以,表和表之间也不应用强关联来表述业务(数据间的一致性),这一职责应由系统的逻辑层来保证,这种方式也确保了系统对于不正确数据(脏数据)的兼容性。当然,从整个系统的角度来说我们还是要尽最大努力确保系统不会产生脏数据,单从另一个角度来说,脏数据的产生在一定程度上也是不可避免的,我们也要保证系统对这种情况的容错性。这是一个折中的方案。

      8.应针对所有表的主键和外键建立索引,有针对性的(针对一些大数据量和常用检索方式)建立组合属性的索引,提高检索效率。虽然建立索引会消耗部分系统资源,但比较起在检索时搜索整张表中的数据尤其时表中的数据量较大时所带来的性能影响,以及无索引时的排序操作所带来的性能影响,这种方式仍然是值得提倡的。

    //索引目前都是DBA根据具体的SQL来创建的,不过开发写SQL时,也应该适当考虑一下字段的索引。

      9.尽量少采用存储过程,目前已经有很多技术可以替代存储过程的功能如"对象/关系映射"等,将数据一致性的保证放在数据库中,无论对于版本控制、开发和部署、以及数据库的迁移都会带来很大的影响。但不可否认,存储过程具有性能上的优势,所以,当系统可使用的硬件不会得到提升而性能又是非常重要的质量属性时,可经过平衡考虑选用存储过程。

    //目前都是杜绝使用存储过程的,我觉得用起来比较方便,对于我们来说,主要原因是会给DBA带来管理方面的麻烦,
    //因为时间一长,存储过程的逻辑和使用场景,往往没人能了解,容易产生更多问题

      10.当处理表间的关联约束所付出的代价(常常是使用性上的代价)超过了保证不会出现修改、删除、更改异常所付出的代价,并且数据冗余也不是主要的问题时,表设计可以不符合四个范式。四个范式确保了不会出现异常,但也可能由此导致过于纯洁的设计,使得表结构难于使用,所以在设计时需要进行综合判断,但首先确保符合四个范式,然后再进行精化修正是刚刚进入数据库设计领域时可以采用的最好办法。

      11.设计出的表要具有较好的使用性,主要体现在查询时是否需要关联多张表且还需使用复杂的SQL技巧。我感觉遵守的范式越多,就越使SQL复杂,具体情况具体分析。设计出的表要尽可能减少数据冗余,确保数据的准确性,有效的控制冗余有助于提高数据库的性能

      因此,考虑了以上条件之后,表设计约定规则如下:

    //规则1:表必须要有主键。
    //规则2:一个字段只表示一个含义。
    //规则3:总是包含两个日期字段:gmt_create(创建日期),gmt_modified(修改日期),且这两个字段不应该包含有额外的业务逻辑。
    //规则4:MySQL中,gmt_create、gmt_modified使用DATETIME类型。
    //规则5:禁止使用复杂数据类型(数组,自定义类型等)。
    //规则6: MySQL中,附属表拆分后,附属表id与主表id保持一致。不允许在附属表新增主键字段。
    //规则7: MySQL中,存在过期概念的表,在其设计之初就必须有过期机制,且有明确的过期时间。过期数据必须迁移至历史表中。
    //规则8: MySQL中,不再使用的表,必须通知DBA予以更名归档。
    //规则9: MySQL中,线上表中若有不再使用的字段,为保证数据完整,禁止删除。
    //规则10: MySQL中,禁止使用OCI驱动,全部使用THI驱动。

    关于MySQL的部分学习笔记总结:

    一、事务跟存储引擎

      1.四种事务隔离级别:read uncommited, read commited(大多数db默认的),repeatable read(mysql默认), seriazable。

      2.mysql是默认的auto commited, 也就是说每次查询默认都是自动提交的(show variables like 'autocommited')。mysql可以通过set transaction isolatioin level命令来设置隔离级别,例如:set session transaction isolation level read commited。

      3.mysql中像innodb采用mvcc(多版本并发控制)来处理并发。mvcc只工作在read commited,repeatable read这两种事务隔离级别上。read uncommited隔离级别不兼容mvcc是因为在该级别得下的查询,不读取符合当前事务版本的数据行,而是最新版本的数据行。seriazable隔离级别不兼容MVCC,因为该级别下的读操作会对每个返回行进行加锁。

      4.选择存储引擎,并发选用myisam,事务选择innodb,myisam比innodb更容易出错,出错了恢复的时间也比较长。只有myisam支持全文检索。

      5.把表从一种存储引擎转到另一种引擎:

    //  1.    alter table mytable engine=falcon;  操作费时,可能会占用服务器的所有i/o处理能力。
    //  2.    create table innodb_table like myisam_table;
    //        alter table innodb_table engine=innodb;
    //        insert into innodb_table select * from myisam_table;

    二、数据类型

      1.尽可能的要把field定义为Not NULL, mysql比较难优化使用了可空列的查询,它会使索引,索引统计更加复杂。可空列需要更多的存储空间,还需要mysql内部进行特殊处理,当可空列被索引时,每条记录都需要一个格外的字节。 即使要在表中存储"没有值"的字段,考虑使用0,特殊字段或者空字符串来代替。

      2.datetime与timestamp能保存同样的数据:精确度为秒,但是timestamp使用的空间只有datetime的一半,还能保存时区,拥有特殊的自动更新能力。但是timestamp保存的时间范围要比datetime要小得多。mysql能存储的最细的时间粒度为秒

      3.mysql支持很多种别名,如bool,integer,nummeric.

      4.float与double类型支持使用标准的浮点运算进行近似计算。 Decimal类型保存精确的小数,在>=mysql5.0,mysql服务器自身进行了decimal的运算,因为CPU不支持直接对它进行运算,所以慢一点。

      5.mysql会把text与blob类型的列当成有实体的对象来进行保存。他们有各自的数据类型家族(tinytext,smalltext,text,mediumtext,longtext; blob类似); mysql对blob与text列排序方式和其他类型有所不同,它不会按照字符串的完整长度来排序。而只是按照max_sort_length规定的若干个字节来进行排序。

      6.采用enum来代替字符串类型。mysql在内部把每个枚举值都保存为整数。enum在内部是按照数字进行排序的,而不是按照字符串。enum最不好的就是字符串列表是固定的,添加和删除必须使用alter table。

      7.ip地址,一般会采用varchar(15)列来保存。事实上,IP地址是个无符号的32位整数,而不是字符串。mysql提供了inet_aton()和inet_nota()函数在证书与ip地址之间进行转换。

    三、索引

      1.聚集索引不仅仅是一种单独的索引类型,而且是一种存储数据的方式。Innodb引擎的聚集索引实际上在同样的结构中保存了B-Tree索引和数据行。当表有聚集索引时,它的数据行实际上保存在索引的叶子上。注意是存储引擎来实现索引。

      2.myisam与innodb数据布局:myisam索引树(无论是主键索引还是非主键索引)叶子节点都是指向的数据行,而innodb中聚集索引,主键索引树叶子节点就带得有数据的内容,而非主键索引树中叶子节点指向主键值,而不是数据的位置。

      3.mysql有两种产生排序结果的方式:使用文件排序,或者扫描有序的索引。目前只有myisam支持全文索引。

      4.myisam表有表级锁;myisam表不支持事务,实际上,myisam并不保证单条命令完成;myisam只缓存了mysql进程内部的索引,并保存在键缓存区内。OS缓存了表的数据;行被紧密的保存在一起,磁盘上的数据有很小的磁盘占用和快速的全表扫描。

      5.innodb支持事务和四种事务隔离级别;在mysql5.0中,只有innodb支持外鍵;支持行级锁与mvcc;所有的innodb表都是按照主键聚集的;所有索引(出开主键)都是按主键引用行;索引没有使用前缀压缩,因此索引可能比myisam大很多;数据转载缓慢;阻塞auto_increment,也就是用表级锁来产生每个auto_increment。

    四、MYSQL性能分析

      1.mysql提供了一个benchmark(int 循环次数,char* 表达式); 可以分析表达式执行所花时间。 例如:

    // select BENCHMARK(10000,SHA1('aaaaaaaaaaaaaaaa'))

      2.mysql有两种查询日志:普通日志和慢速日志。

    五、MYSQL高级特性

      1.在mysql中,只有myisam存储引擎支持全文索引。myisam全文索引是一种特殊的具有两层结构的B树。

      2.存储引擎事务在存储引擎内部被赋予acid属性,分布式(XA)是一种高层次事务,它可以历哟内部个两段提交的方式将acid属性扩展到存储引擎外部,甚至数据库外部。阶段1:通知所有提交者准备提交 阶段2:通知所有参与者进行真正提交。

      3.mysql 的字符集和校对规则有 4 个级别的默认设置:服务器级、数据库级、表级和字段级。Mysql4.1 开始支持 SQL 的子查询。

    /******************************************/
    /*   数据库全名 = degopen@10.218.249.92:3318【mysql】   */
    /*    表名称 = task_new   */
    /******************************************/
    CREATE TABLE `task_new` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
      `task_name` varchar(128) NOT NULL COMMENT '任务名称',
      `image` varchar(128) DEFAULT NULL COMMENT '任务图标',
      `description` varchar(1024) NOT NULL COMMENT '任务描述',
      `content` varchar(1024) NOT NULL COMMENT '任务内容',
      `finished_message` varchar(128) DEFAULT NULL COMMENT '任务完成提示信息',
      `task_scope` int(11) NOT NULL COMMENT '任务范围, 0-平台任务, 1-游戏任务',
      `series_task` int(11) NOT NULL DEFAULT '0' COMMENT '任务类型: 系列任务,单独任务',
      `task_type` int(11) NOT NULL DEFAULT '0' COMMENT '任务类型: 固定任务, 推广任务, 日常任务',
      `pre_task` varchar(128) DEFAULT NULL COMMENT '前置任务',
      `post_task` varchar(128) DEFAULT NULL COMMENT '后置任务',
      `task_status` int(11) NOT NULL COMMENT '任务状态, 待审核、未开始、生效中、已暂停、已完成、审核未通过',
      `auto_task` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否手动任务, 0-否, 1-是',
      `is_required` tinyint(4) NOT NULL COMMENT '是否必须任务',
      `event_type` varchar(64) DEFAULT NULL COMMENT '关心的事件类型',
      `task_target` bigint(20) DEFAULT '0' COMMENT '任务目标',
      `reset_num` int(11) NOT NULL COMMENT '重置次数',
      `reset_cycle` int(11) NOT NULL COMMENT '重置周期',
      `task_interval` int(11) NOT NULL COMMENT '任务间隔',
      `xiaoer` bigint(20) unsigned NOT NULL COMMENT '创建人',
      `review_id` bigint(20) unsigned NOT NULL COMMENT '审核人ID',
      `last_start_time` datetime DEFAULT NULL COMMENT '上次生效时间',
      `gmt_create` datetime NOT NULL COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL COMMENT '修改时间',
      `start_time` datetime NOT NULL COMMENT '开始时间',
      `end_time` datetime NOT NULL COMMENT '结束时间',
      `start_condition` varchar(1024) NOT NULL COMMENT '任务触发条件',
      `end_condition` varchar(1024) NOT NULL COMMENT '任务完成条件',
      `enable` tinyint(4) NOT NULL DEFAULT '1' COMMENT '是否可用',
      `rule` varchar(4096) NOT NULL COMMENT '任务规则',
      `priority` int(11) NOT NULL DEFAULT '1' COMMENT '任务优先级',
      `progress_rule` varchar(2048) NOT NULL DEFAULT '' COMMENT '进度计算规则',
      `order_no` int(11) DEFAULT '1' COMMENT '排序号',
      `classification` int(11) DEFAULT '0' COMMENT '0:默认分类\n1:玩游戏\n2:抽奖',
      `level` int(11) DEFAULT '0' COMMENT '针对同一个分类,不同的等级',
      `ext1` longtext COMMENT '扩展字段1(UU中使用该字段指示按钮跳转)',
      `ext2` longtext COMMENT '扩展字段2,暂时预留',
      `channel` int(11) DEFAULT '0' COMMENT '任务渠道:0-uu或者1-game_box',
      `consecutive_day` int(11) DEFAULT '1' COMMENT '连续完成任务的天数',
      `activity` varchar(256) DEFAULT 'default' COMMENT '任务所属的活动名字',
      `device` text COMMENT '机型',
      `packages` text COMMENT '应用',
      PRIMARY KEY (`id`),
      KEY `name_channel` (`task_name`,`channel`),
      KEY `activity` (`activity`(255))
    ) ENGINE=InnoDB AUTO_INCREMENT=1194 DEFAULT CHARSET=utf8 COMMENT='任务表';

     

    转载于:https://www.cnblogs.com/RunForLove/p/5693986.html

    展开全文
  • 聊聊数据库表结构设计心得

    千次阅读 2020-07-22 12:09:03
    本文讨论是一般设计,有一定的普遍性和通用性,当然对于特殊性的考量则不在本文讨论之列。 自增 id Java 层的 CRUD 都是围绕自增 id 的,以这个 id 为依据的,所以自增 id 不可或缺,每张都应该有。当然其他...

    本文讨论是一般表的设计,有一定的普遍性和通用性,当然对于特殊性的考量则不在本文讨论之列。

    自增 id

    Java 层的 CRUD 都是围绕自增 id 的,以这个 id 为依据的,所以自增 id 不可或缺,每张表都应该有。当然其他类型的 id,如 uuid、雪花 id 都可以并存。

    还有分页、表与表的关联都离不开这个自增 id。

    createDate & updateDate

    有了这两个字段,你可以追溯到数据的时间点,创建和修改的时间点,以方便查找问题。MySQL 下类型为 datetime,在 Service 层控制生成。一般精确到秒即可,如果并发量大可以考虑毫秒级别的。

    creator & updater

    同理,创建人& 修改人也是为了出问题的时候可以追溯起因用的,相当于日志的作用。但是这两个字段可以斟酌使用,因为涉及表关联(外连接到用户表)比较麻烦。

    唯一标识

    特点是全局唯一,在处理通用表的时候很好用,例如附件表,一个实体可以拥有多个附件,即一对多,那么在附件表里面有个 ownerId 对应那个实体即可,无须额外增加字段再说明哪种类型。当然于附件表本身而言,他并不知道对应的类型,要靠实体主动关联它的时候,才晓得。

    唯一标识生成算法很多,我们架构采用 Twitter 的“雪花算法”。

    状态 status

    如果不是物理删除某行记录,那么就在数据库上面标记之。如设一 isDeleted 字段,不是不行,是每张表都要那么做。还有我们的表多数时候考虑一个“上线/下线”的状态,获取其他特定的状态。那么何不干脆将它们合并之?统一一个 status 字段好了。MySQL status 是关键字,你可改名 stat 或转义。

    MySQL 下设置 TinyInt(1) 类型即可,对应 Java 设计好的常量,例如 0/null = 正常/上线状态,1=下线,2=已删除,……=不断扩充。

    表关联

    尽量不要有冗余的信息数据,否则你需要更新同一份信息的时候,需要更新多个地方。数据库三大范式能遵守就遵守,实在不行也不必过于拘泥,例如权衡性能的话,有时需要冗余部分数据。

    外键、触发器

    外键是老一代的东东,不要为自己添加枷锁。触发器看情况,虽然大部分可以用 Java 代替之,但有时妙用也可以。

    存储过程、函数

    老一代很喜欢用,现在通通给我用 Java 写。但有时 SQL 没法实现,就应该请益于它们了,例如 MySQL 递归查询。

    分库分表

    这方面本人经验不是很多,——另请看高人的——
    在这里插入图片描述
    出处 https://developer.aliyun.com/article/756689

    其他杂项

    数据库表名,应该用复数还是单数?

    用单数形式更佳,参考 http://www.cnblogs.com/jiqing9006/p/4999670.html

    varchar(255) 还是 varchar(256)?

    tinyint 类型存储的最大数字是 255,诱导我们设置 varchar 时也不要突破 255,实际上 tinyint 存储的是 0-255 一共 256 个数字。
    但是,实际上建议使用 varchar(256),因为这是一个字节的内容,微软设计的数据库中使用的就是 256,而不是 255。

    数据库版本号

    参见:《数据库模型设计:历史与版本设计》 https://blog.csdn.net/studyzy/article/details/11524649

    通用结构

    综上所述,给出表结构的通用字段如下。

    CREATE TABLE `template` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键 id,自增',
      `name` varchar(45) DEFAULT NULL COMMENT '名称',
      `content` text COMMENT '内容',
      `uid` bigint(20) NOT NULL COMMENT '唯一 id,通过 uuid 生成不重复 id',
      `createByUser` int(11) DEFAULT NULL COMMENT '创建者 id',
      `createDate` datetime NOT NULL COMMENT '创建日期',
      `updateDate` datetime NOT NULL COMMENT '修改日期',
      `stat` tinyint(2) DEFAULT NULL COMMENT '是否已删除 1=已删除;0/null;未删除',
      `catelogId` int(11) DEFAULT NULL COMMENT '分类 id',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='模版结构';
    
    展开全文
  • EZDML数据库表结构设计

    千次阅读 2019-04-29 09:43:55
    EZDML下载地址 链接:https://pan.baidu.com/s/1jEH_uABGC1d4NoY3sstNdQ 提取码:qnis 复制这段内容后打开百度网盘手机App,操作更方便哦
  • mysql 数据库表结构设计与规范

    千次阅读 2017-06-06 15:00:16
    mysql 数据库表结构设计与规范DDL(data difinition language)就是数据定义语言。1.sql语句的界定符[code]– 默认情况下” ; ” 代表sql语句的结束 delimiter 新的界定符 – 修改 // 为界定符 delimiter //2.创建...
  • 博客|朋友圈 数据库表结构设计

    千次阅读 2019-05-23 18:56:42
    个人博客(一)之表结构设计 朋友圈表结构 一个是发布。发布数据记录了来自所有用户所有的feed,比如一个用户发布了几张图片,每张图片的URL是什么,在CDN里的URL是什么,它有哪些元属性,谁可以看,谁不可以...
  • 数据库表结构设计的一些总结

    千次阅读 2017-10-27 16:48:12
    前言最近在工作中遇到了一些关于表结构设计的问题,我所在的公司,在表设计的时候有三个字段必须要有,create_time、update_time、version。这些字段也是大多数公司都会要求的,create_time记录创建时间,update_...
  • 用户权限管理数据库表结构设计

    千次阅读 2017-07-27 15:21:55
    实现业务系统中的用户权限管理--设计篇  B/S系统中的权限比C/S中的更显的重要,C/S系统因为具有特殊的客户端,所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现,而B/S中,浏览器是每一台...
  • 导出 MySQL 数据库表结构设计文档

    千次阅读 2020-01-08 14:44:54
    在我寻找导出文档工具的过程中,有幸碰到一个博主的文章,是关于java导出mysql或者oracle数据库表结构设计文档 链接: https://www.jianshu.com/p/884aff422649 项目下载运行之后: 如上填写完信息之后 ...
  • app 商城数据库表结构设计

    万次阅读 2017-02-25 14:28:16
    近期公司要着手一个商城的项目,后台那边暂时有项目。让我设计一下数据库。这是我总结设计的,记录下日后完善。
  • MySQL数据库表结构设计

    万次阅读 多人点赞 2019-05-28 13:51:56
    MySQL数据库表结构设计。四大范式。表结构的设计是数据库优化中至关重要的环节,需要认真谨慎对待,在遵守四大范式的前提下,充分考虑业务未来的可扩展性,适应未来业务变化,促进系统更加健康健壮。
  • 数据库表结构设计--动态字段

    万次阅读 2018-04-29 13:05:54
    用户提出了无限扩展团员属性和随时修改属性名的要求两大难题:不定字段数目的数据库表设计和数据结构1、不定字段数目的数据库表的设计(需要一张单独的表来管理这个这些字段名)2、访问层的数据结构设计(动态的表...
  • 关于聊天记录数据库表结构设计

    千次阅读 2018-06-07 12:00:00
    1、首先表结构设计针对单个用户,然后拓展到n个用用户记录的存储。 2、这里会用msql数据库给出数据库表脚本,但是实际生产环境应该是在APP端生成sqlite数据库文件,把sqlite文件上传到server端作为聊天记录存储。 有...
  • 金蝶EAS7.5数据库表结构,带联动。点击表结构中文名称可以查看表字段及说明,可返回。
  • 选择表,右键-对象信息 这样就能看到表结构图了 红色圈圈那里可以上下拉动
  • MySQL数据库表结构设计优化技巧总结

    千次阅读 2015-02-09 15:51:05
    很多人都将 数据库设计范式 作为数据库表结构设计“圣经”,认为只要按照这个范式需求设计,就能让设计出来的表结构足够优化,既能保证性能优异同时还能满足扩展性要求。殊不知,在N年前被奉为“圣经”的数据库...
  • 二,初步分析用户和角色 说到权限管理,首先应该想到,当然要设计一个用户,一个权限。这样就决定了一个人有什么样的权限。做着做着就会发现这样设计太过繁琐,如果公司里面所有员工都有这样的权限呢,每一个人...
  • 数据库多级联动表结构设计

    千次阅读 2020-08-11 21:27:39
    建立多个数据库表,低级表结构中只包含上一级表中id。 省表 市表 区表 县表 province city district county id province_id city_id district_id 优点: 此设计完全解开了各层...
  • 某HIS数据库表结构

    2017-11-25 18:57:07
    某HIS数据库表结构 大概有100多个表,是一份比较详细的数据字典,可以用作数据库设计的参考
  • FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'crm' // crm =数据库名 AND table_name = 'sys_user' // sys_user =表名 剩下的属性: 上述SQL执行后: 然后点击“导出表格”: 然后: 然后: 下一步...
  • 基于.net 4.0开发的数据库表结构说明文档自动生成工具,可自动生成word或html格式,支持数据库类型有:mysql、sqlserver、oracle
  • 禅道的数据库表结构

    2014-10-28 01:22:13
    赶紧的下载哦,是创建数据库的语句来的,姐不骗你,禅道的数据库表结构,最新的哦,赶紧的,大家学习下。
  • LIS数据库表结构

    2015-08-07 10:18:15
    我也是在网上找到的,搬到了这里. 如果有好的表结构的资源,可以Q我,大家一起学习交流. 我也是在不断的探索中~

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 472,622
精华内容 189,048
关键字:

数据库表结构设计