`

<转>数据库设计表和字段的经验

阅读更多

检查各种变化

我在设计数据库的时候会考虑到哪些数据字段将来可能会发生变更。比方说,姓氏就是如此(注意是西方人的姓氏,比如女性结婚后从夫姓等)。所以,在建立系统存储客户信息时,我倾向于在单独的一个数据表里存储姓氏字段,而且还附加起始日和终止日等字段,这样就可以跟踪这一数据条目的变化。

采用有意义的字段名

有一回我参加开发过一个项目,其中有从其他程序员那里继承的程序,那个程序员喜欢用屏幕上显示数据指示用语命名字段,这也不赖,但不幸的是,她还喜欢用一些奇怪的命名法,其命名采用了匈牙利命名和控制序号的组合形式,比如 cbo1、txt2、txt2_b 等等。

除非你在使用只面向你的缩写字段名的系统,否则请尽可能地把字段描述的清楚些。当然,也别做过头了,比如 Customer_Shipping_Address_Street_Line_1,虽然很富有说明性,但没人愿意键入这么长的名字,具体尺度就在你的把握中。

采用前缀命名

如果多个表里有好多同一类型的字段(比如 FirstName),你不妨用特定表的前缀(比如 CusLastName)来帮助你标识字段。

时效性数据应包括“最近更新日期/时间”字段。时间标记对查找数据问题的原因、按日期重新处理/重载数据和清除旧数据特别有用。

标准化和数据驱动

数据的标准化不仅方便了自己而且也方便了其他人。比方说,假如你的用户界面要访问外部数据源(文件、XML 文档、其他数据库等),你不妨把相应的连接和路径信息存储在用户界面支持表里。还有,如果用户界面执行工作流之类的任务(发送邮件、打印信笺、修改记录状态等),那么产生工作流的数据也可以存放在数据库里。预先安排总需要付出努力,但如果这些过程采用数据驱动而非硬编码的方式,那么策略变更和维护都会方便得多。事实上,如果过程是数据驱动的,你就可以把相当大的责任推给用户,由用户来维护自己的工作流过程。

标准化不能过头

对那些不熟悉标准化一词(normalization)的人而言,标准化可以保证表内的字段都是最基础的要素,而这一措施有助于消除数据库中的数据冗余。标准化有好几种形式,但 Third Normal Form(3NF)通常被认为在性能、扩展性和数据完整性方面达到了最好平衡。简单来说,3NF 规定:

* 表内的每一个值都只能被表达一次。

* 表内的每一行都应该被唯一的标识(有唯一键)。

* 表内不应该存储依赖于其他键的非键信息。

遵守 3NF 标准的数据库具有以下特点:有一组表专门存放通过键连接起来的关联数据。比方说,某个存放客户及其有关定单的 3NF 数据库就可能有两个表:Customer 和 Order。Order 表不包含定单关联客户的任何信息,但表内会存放一个键值,该键指向 Customer 表里包含该客户信息的那一行。

更高层次的标准化也有,但更标准是否就一定更好呢?答案是不一定。事实上,对某些项目来说,甚至就连 3NF 都可能给数据库引入太高的复杂性。

为了效率的缘故,对表不进行标准化有时也是必要的,这样的例子很多。曾经有个开发餐饮分析软件的活就是用非标准化表把查询时间从平均 40 秒降低到了两秒左右。虽然我不得不这么做,但我绝不把数据表的非标准化当作当然的设计理念。而具体的操作不过是一种派生。所以如果表出了问题重新产生非标准化的表是完全可能的。

Microsoft Visual FoxPro 报表技巧

如果你正在使用 Microsoft Visual FoxPro,你可以用对用户友好的字段名来代替编号的名称:比如用 Customer Name 代替 txtCNaM。这样,当你用向导程序 [Wizards,台湾人称为‘精灵’] 创建表单和报表时,其名字会让那些不是程序员的人更容易阅读。

不活跃或者不采用的指示符

增加一个字段表示所在记录是否在业务中不再活跃挺有用的。不管是客户、员工还是其他什么人,这样做都能有助于再运行查询的时候过滤活跃或者不活跃状态。同时还消除了新用户在采用数据时所面临的一些问题,比如,某些记录可能不再为他们所用,再删除的时候可以起到一定的防范作用。

使用角色实体定义属于某类别的列[字段],在需要对属于特定类别或者具有特定角色的事物做定义时,可以用角色实体来创建特定的时间关联关系,从而可以实现自我文档化。

这里的含义不是让 PERSON 实体带有 Title 字段,而是说,为什么不用 PERSON 实体和 PERSON_TYPE 实体来描述人员呢?比方说,当 John Smith, Engineer 提升为 John Smith, Director 乃至最后爬到 John Smith, CIO 的高位,而所有你要做的不过是改变两个表 PERSON 和 PERSON_TYPE 之间关系的键值,同时增加一个日期/时间字段来知道变化是何时发生的。这样,你的 PERSON_TYPE 表就包含了所有 PERSON 的可能类型,比如 Associate、Engineer、Director、CIO 或者 CEO 等。还有个替代办法就是改变 PERSON 记录来反映新头衔的变化,不过这样一来在时间上无法跟踪个人所处位置的具体时间。

采用常用实体命名机构数据

组织数据的最简单办法就是采用常用名字,比如:PERSON、ORGANIZATION、ADDRESS 和 PHONE 等等。当你把这些常用的一般名字组合起来或者创建特定的相应副实体时,你就得到了自己用的特殊版本。开始的时候采用一般术语的主要原因在于所有的具体用户都能对抽象事物具体化。

有了这些抽象表示,你就可以在第 2 级标识中采用自己的特殊名称,比如,PERSON 可能是 Employee、Spouse、Patient、Client、Customer、Vendor 或者 Teacher 等。同样的,ORGANIZATION 也可能是 MyCompany、MyDepartment、Competitor、Hospital、Warehouse、Government 等。最后 ADDRESS 可以具体为 Site、Location、Home、Work、Client、Vendor、Corporate 和 FieldOffice 等。

采用一般抽象术语来标识“事物”的类别可以让你在关联数据以满足业务要求方面获得巨大的灵活性,同时这样做还可以显著降低数据存储所需的冗余量。

用户来自世界各地

在设计用到网络或者具有其他国际特性的数据库时,一定要记住大多数国家都有不同的字段格式,比如邮政编码等,有些国家,比如新西兰就没有邮政编码一说。

数据重复需要采用分立的数据表

如果你发现自己在重复输入数据,请创建新表和新的关系。

每个表中都应该添加的 3 个有用的字段

* dRecordCreationDate,在 VB 下默认是 Now(),而在 SQL Server 下默认为 GETDATE()

* sRecordCreator,在 SQL Server 下默认为 NOT NULL DEFAULT USER

* nRecordVersion,记录的版本标记;有助于准确说明记录中出现 null 数据或者丢失数据的原因

对地址和电话采用多个字段

描述街道地址就短短一行记录是不够的。Address_Line1、Address_Line2 和 Address_Line3 可以提供更大的灵活性。还有,电话号码和邮件地址最好拥有自己的数据表,其间具有自身的类型和标记类别。

过分标准化可要小心,这样做可能会导致性能上出现问题。虽然地址和电话表分离通常可以达到最佳状态,但是如果需要经常访问这类信息,或许在其父表中存放“首选”信息(比如 Customer 等)更为妥当些。非标准化和加速访问之间的妥协是有一定意义的。

使用多个名称字段

我觉得很吃惊,许多人在数据库里就给 name 留一个字段。我觉得只有刚入门的开发人员才会这么做,但实际上网上这种做法非常普遍。我建议应该把姓氏和名字当作两个字段来处理,然后在查询的时候再把他们组合起来。

我最常用的是在同一表中创建一个计算列[字段],通过它可以自动地连接标准化后的字段,这样数据变动的时候它也跟着变。不过,这样做在采用建模软件时得很机灵才行。总之,采用连接字段的方式可以有效的隔离用户应用和开发人员界面。

提防大小写混用的对象名和特殊字符

过去最令我恼火的事情之一就是数据库里有大小写混用的对象名,比如 CustomerData。这一问题从 Access 到 Oracle 数据库都存在。我不喜欢采用这种大小写混用的对象命名方法,结果还不得不手工修改名字。想想看,这种数据库/应用程序能混到采用更强大数据库的那一天吗?采用全部大写而且包含下划符的名字具有更好的可读性(CUSTOMER_DATA),绝对不要在对象名的字符之间留空格。

小心保留词

要保证你的字段名没有和保留词、数据库系统或者常用访问方法冲突,比如,最近我编写的一个 ODBC 连接程序里有个表,其中就用了 DESC 作为说明字段名。后果可想而知!DESC 是 DESCENDING 缩写后的保留词。表里的一个 SELECT * 语句倒是能用,但我得到的却是一大堆毫无用处的信息。

保持字段名和类型的一致性

在命名字段并为其指定数据类型的时候一定要保证一致性。假如字段在某个表中叫做“agreement_number”,你就别在另一个表里把名字改成“ref1”。假如数据类型在一个表里是整数,那在另一个表里可就别变成字符型了。记住,你干完自己的活了,其他人还要用你的数据库呢。

仔细选择数字类型

在 SQL 中使用 smallint 和 tinyint 类型要特别小心,比如,假如你想看看月销售总额,你的总额字段类型是 smallint,那么,如果总额超过了 $32,767 你就不能进行计算操作了。

删除标记

在表中包含一个“删除标记”字段,这样就可以把行标记为删除。在关系数据库里不要单独删除某一行;最好采用清除数据程序而且要仔细维护索引整体性。

避免使用触发器

触发器的功能通常可以用其他方式实现。在调试程序时触发器可能成为干扰。假如你确实需要采用触发器,你最好集中对它文档化。

包含版本机制

建议你在数据库中引入版本控制机制来确定使用中的数据库的版本。无论如何你都要实现这一要求。时间一长,用户的需求总是会改变的。最终可能会要求修改数据库结构。虽然你可以通过检查新字段或者索引来确定数据库结构的版本,但我发现把版本信息直接存放到数据库中不更为方便吗?。

给文本字段留足余量

ID 类型的文本字段,比如客户 ID 或定单号等等都应该设置得比一般想象更大,因为时间不长你多半就会因为要添加额外的字符而难堪不已。比方说,假设你的客户 ID 为 10 位数长。那你应该把数据库表字段的长度设为 12 或者 13 个字符长。这算浪费空间吗?是有一点,但也没你想象的那么多:一个字段加长 3 个字符在有 1 百万条记录,再加上一点索引的情况下才不过让整个数据库多占据 3MB 的空间。但这额外占据的空间却无需将来重构整个数据库就可以实现数据库规模的增长了。身份证的号码从 15 位变成 18 位就是最好和最惨痛的例子。

列[字段]命名技巧

我们发现,假如你给每个表的列[字段]名都采用统一的前缀,那么在编写 SQL 表达式的时候会得到大大的简化。这样做也确实有缺点,比如破坏了自动表连接工具的作用,后者把公共列[字段]名同某些数据库联系起来,不过就连这些工具有时不也连接错误嘛。举个简单的例子,假设有两个表:

Customer 和 Order。Customer 表的前缀是 cu_,所以该表内的子段名如下:cu_name_id、cu_surname、cu_initials 和cu_address 等。Order 表的前缀是 or_,所以子段名是:or_order_id、or_cust_name_id、or_quantity 和 or_description 等。

这样从数据库中选出全部数据的 SQL 语句可以写成如下所示:

 

Select * From Customer, Order Where cu_surname = "MYNAME" ;
                        and cu_name_id = or_cust_name_id and or_quantity = 1

在没有这些前缀的情况下则写成这个样子(用别名来区分):

 

Select * From Customer, Order Where Customer.surname = "MYNAME" ;
                        and Customer.name_id = Order.cust_name_id and Order.quantity = 1

第 1 个 SQL 语句没少键入多少字符。但如果查询涉及到 5 个表乃至更多的列[字段]你就知道这个技巧多有用了。

分享到:
评论

相关推荐

    C#+List+GridControl实现主从表嵌套

    本篇将深入探讨如何利用`C#`中的`List&lt;T&gt;`集合类以及DevExpress的`GridControl`控件实现主从表的嵌套显示,这在数据库操作和数据可视化中非常常见。 `List&lt;T&gt;`是.NET Framework中`System.Collections.Generic`命名...

    C#编程经验技巧宝典

    C#编程经验技巧宝典源代码,目录如下:&lt;br&gt;第1章 开发环境 1&lt;br&gt;&lt;br&gt;1.1 Visual Studio开发环境安装与配置 2&lt;br&gt;&lt;br&gt;0001 安装Visual Studio 2005开发环境须知 2&lt;br&gt;&lt;br&gt;0002 配置合适的Visual Studio 2005...

    数据库编程规范

    注意事项 &lt;br&gt;l 索引 &lt;br&gt; 每一张表必须有一个主键 &lt;表名&gt;_pk &lt;br&gt; 若干外键索引 &lt;表名&gt;_fk_&lt;数字&gt; &lt;br&gt; 若干其它索引 &lt;表名&gt;_&lt;数字&gt; &lt;br&gt;l 数据类型 &lt;br&gt; 定义合适的数据类型,注意 例如: &lt;br&gt; amount number(9,2)...

    SQL2005入门到精通(4)

    55&lt;br&gt;4.5.5 删除字段 55&lt;br&gt;4.6 数据表的浏览 56&lt;br&gt;4.6.1 查看表中所有记录 56&lt;br&gt;4.6.2 查看表的某条记录 56&lt;br&gt;4.7 数据表中数据的维护 57&lt;br&gt;4.7.1 添加新的记录 57&lt;br&gt;4.7.2 修改现有记录 58&lt;br&gt;4.7.3 删除...

    AppFramework数据库访问组件_代码生成插件_V1.1.rar

    &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;下面三张表格罗列的测试数据,可以明显看出AppFramework数据库访问组件的性能全面超越了IBatisNet: &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;表I –10并发20循环(数据库和测试机分开)&lt;br&gt;&lt;br&gt;对比项目&lt;br&gt;iBatis2.0&lt;br&gt;...

    ASP与SQL网页数据库程序设计

    3 关系型数据库 48&lt;br&gt;3-3-1 数据的表示方法 48&lt;br&gt;3-3-2 表 49&lt;br&gt;3-3-3 键 50&lt;br&gt;3-3-4 表索引 50&lt;br&gt;3-3-5 视图 51&lt;br&gt;3-3-6 存储过程 52&lt;br&gt;3-3-7 触发器 53&lt;br&gt;3-3-8 数据目录 54&lt;br&gt;3-4 数据库设计 55...

    数据库设计和自动安装工具BDB V2.2(for Oracle/MS SQLServer/MySQL/Access/SQLAnywhere/Sybase)

    &lt;br&gt;&lt;br&gt;此外、在BDB中提供了对开发语言的支持、&lt;br&gt;其数据库结构定义文件采用XML标准格式、&lt;br&gt;并且开放了外部读取数据库结构的源程序(C#/Delphi/JAVA)、&lt;br&gt;您可以通过使用BDB来简化软件开发和部署过程:&lt;br&gt;&lt;br&gt;1...

    AppFramework_V1.0

    1.48&lt;br&gt;&lt;br&gt;1.16&lt;br&gt; &lt;br&gt;查询结果集(平均101行)&lt;br&gt;&lt;br&gt;(1循环200次select)&lt;br&gt; 1055.1&lt;br&gt; 666.8&lt;br&gt;&lt;br&gt;不定字段:710.1&lt;br&gt; 1.58&lt;br&gt;&lt;br&gt;1.50&lt;br&gt; &lt;br&gt;&lt;br&gt; &lt;br&gt;&lt;br&gt;表III –50并发10循环(数据库和测试机同机...

    AppFramework_V1.0_New

    &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;下面三张表格罗列的测试数据,可以明显看出AppFramework数据库访问组件的性能全面超越了IBatisNet: &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;表I –10并发20循环(数据库和测试机分开)&lt;br&gt;&lt;br&gt;对比项目&lt;br&gt;iBatis2.0&lt;br&gt;...

    mysql5.1中文手册

    mysqlshow-显示数据库、表和列信息&lt;br&gt;8.12. myisamlog:显示MyISAM日志文件内容&lt;br&gt;8.13. perror:解释错误代码&lt;br&gt;8.14. replace:字符串替换实用工具&lt;br&gt;8.15. mysql_zap:杀死符合某一模式的进程&lt;br&gt;9. 语言...

    C#.net_经典编程例子400个

    55&lt;br&gt;实例052 为TextBox控件添加列表选择框 57&lt;br&gt;2.2 Button控件应用 58&lt;br&gt;实例053 在Button按钮中显示图标 58&lt;br&gt;2.3 ComboBox控件应用 59&lt;br&gt;实例054 将数据表中的字段添加到ComboBox控件 59&lt;br&gt;实例...

    SpringBoot + MybatisPlus 实现实体类转成数据库表结构,可直接运行

    在开发过程中,有时候我们可能需要快速地根据实体类创建数据库表结构,特别是在数据表丢失或者没有备份的情况下。...同时,合理设计实体类,确保它们符合数据库设计的最佳实践,比如遵循第三范式,避免冗余数据。

    SQL Server数据库设计表和字段的经验

    设计表和字段时,需要预估未来可能的数据变动,例如西方人的姓氏可能因婚姻等原因发生变化。因此,建议为变动频繁的数据创建独立的表,并添加开始日期和结束日期字段,以便追踪数据历史。 在选择字段名时,应遵循有...

    SQL智能完成工具BDB

    (同时支持ALT+ENTER键直接执行,&lt;br&gt;和CTRL+ENTER的区别:ALT+ENTER是执行原始语法,而前者则会进行解析,&lt;br&gt;如“DESC”语法)。&lt;br&gt;&lt;br&gt;2、和SQLSERVER的查询分析器一样,支持鼠标选择部分语法执行。&lt;br&gt;&lt;br&gt;3、...

    数据库应用技术:表的常规操作.pptx

    数据库应用技术是计算机科学中的一门重要技术,它涉及到数据库的设计、开发、实现和维护。数据库是一种高效的数据存储和管理系统,它能够存储大量的数据,并提供快速的数据检索和处理能力。 在本节中,我们将介绍...

    全功能的数据库工具BDB v2.8

    BDB是贝恩软件(www.bainsoft.com)发布的数据库设计和数据库部署软件。&lt;br&gt;支持Oracle、SQLServer、MySQL、Access、SQLAnywhere和Sybase。&lt;br&gt;&lt;br&gt;BDB同时是非常好用的SQL智能化查询分析工具。&lt;br&gt;&lt;br&gt;如果您目前...

    数据库表设计命名规范.doc

    1. 格式固定:索引名格式为"IDX_table_&lt;table&gt;_&lt;column&gt;",表明索引所在的表和字段。 2. 长度控制:索引名不超过30字符,超长时缩写。 主键和外键的命名: 1. 主键:以"PK_&lt;table&gt;"命名,&lt;table&gt;是表名。 2. 唯一键...

    ERP学习教程

    简明手册&lt;br&gt;§8 OA-ERP简明手册&lt;br&gt;&lt;br&gt;第三部分 系统高级设计&lt;br&gt;§9 OA-ERP系统数据库的结构&lt;br&gt;§10 OA-ERP系统界面自定义设置&lt;br&gt;§11 OA-ERP语言、时区&lt;br&gt;§12 打印报表设计字段漫游取值&lt;br&gt;§13 导航信息...

    金蝶 KIS专业版10数据库表和字段详细说明

    总之,金蝶KIS专业版10的数据库设计是整个系统运行的基础,深入理解这些数据库表和字段的功能和结构,对于企业IT人员进行数据分析、系统升级和问题排查都具有极高的价值。通过对“K3数据库详细说明”文件的深入学习...

    为数据库表设计可扩展的字段

    在数据库设计中,确保表结构具有良好的扩展性是至关重要的,因为这直接影响到系统的灵活性、维护性和性能。本文将深入探讨如何为数据库表设计可扩展的字段,以便在未来的需求变化或业务扩展时能够轻松应对。 首先,...

Global site tag (gtag.js) - Google Analytics