数据库设计(1/9):数据元(Data Elements)
对于设计和创建数据库完全是个新手?没关系,Joe Celko,世界上读者数量最多的SQL作者之一,会告诉你这些基础。和往常一样,即使是最专业的数据库老手,也会给他们带来惊喜。Joe是DMBS杂志是多年来最受读者喜爱的作者。他在美国、英国,北欧,南美及非洲传授SQL知识。他在ANSI / ISO SQL标准委员会工作了10年,为SQL-89和SQL-92标准做出了杰出贡献。
在你开始考虑你的数据库架构或表前,你需要细想下你的数据:数据是什么类型,你使用值的范围。它应该是唯一的,精确的且不含糊的。然后你的命名应该通俗易懂的。Joe Celko这样解释道。
不要太惊讶,在数据库设计里第一步是数据。但事实上,太多的程序员不会花时间在它们的数据设计上,而是首先设计架构。这样行不通。SQL处理的是结构化数据,而不是想文本或图片的非结构化数据。在关系型数据库管理系统(RDBMS)里一个基本概念是Codd博士所谓的信息原则(Information Principle)。这个规则写道:在关系型数据库管理系统里,所有的数据被建模为表里行里列里的标量。
这就是说表里的所有行有同样的结构。也就是说正确的表设计不会出现有一行是汽车的模型,另一行是鱿鱼的模型,还有一行表示Lady Gaga。
同样,这就是说行里的每列是同样数据元的值。在表里,一个列不会从鞋子大小变成其它温度的值。也就是说范围不会改变——如果你以摄氏度测量温度,那么这列的所有值都使用摄氏度的范围。
选择数据的范围和类型很重要。它让在一些范围内做数学和比较有意义,而不是与其它。这也解释了为什么SQL 是强类型语言(strongly typed language)。一些语言是弱类型的——那就是,变量在程序执行期间可以修改数据类型——一些则是强类型的;那些就是变量保持同样的数据类型,只有你在强制转化的时候才会是新的数据类型。并不是所有的强制转化都合法。弱类型转化问题的经典例子是PL/I里,如果你分配单个数组元为负数的平方根,它会把整个数组从FLOAT转为COMPLEX类型。这个发生的时候没有任何警告信息。关于弱数据类型有个老笑话:
教师:“比利,6乘以9多少?”
比利:“额~~,红色?”
教师:“不是!萨利,6乘以9多少?”
萨利:“星期四?”
教师:“不是!汤米,6乘以9多少?”
汤米:“54”
教师:“回答正确!现在告诉大家你怎么得到答案的。”
汤米:“我用红色除以星期四!”
人们在写弱类型语言时,经常会在数据元名称加上前缀或词尾,告诉大家原始数据类型,防止在程序中大家修改类型。这违反了ISO-11179元数据规则。这个标准总结了命名数据元是它本身应该是什么,而不是它在存储中的位置,或者在表里如何使用。
对于数据元,ISO_11179格式是“[<角色>_]<属性名>_<特征名>]"(“[<role>_]<attribute>_<property>”)。在整个架构里,一个数据元有一个且只有一个名称。如果在整个企业里有且只有一个名称更佳。最好的话,在宇宙里有且只有一个名称。我来告诉你另一个老笑话:
“我是小孩时,我们有三只猫。”
“它们的名字是什么?”
“猫,猫和猫。”
“听起来分不清;你怎么把它们区分开?”
“谁在乎呢?当你叫它们时,它们也不会过来!”
我们希望数据在叫的时候就知道它是什么。逻辑上称同一律(the Law of Identity),通常简单的从字面上说A就是A。更正式的话,我们称作:
- “是”就特指某物;实体应有名称。
- “不是”任何特定之物,就彻底不是任何事物;实体应是唯一且精确的。
- “是”任何一般之物,就彻底不是任何(其它)事物;实体应无二义性。
例如,没有一个东西可以是“id”——它太模糊,太通用(它是用来标识汽车,鱿鱼还是布兰妮·斯皮尔斯么?)。它是没有性质的属性。更好的命名会是”vehicle_id",如果那是我们有的属性性质(attribute property)。最好的数据元名称是“vin”,这个是普遍使用和定义的ISO 4030“车辆识别码(Vehicle Identification Number)”标准。VIN精确且很好理解。
同样,你也会看到没有性质的属性。我个人最爱的是“sex”,它可以是“sex_code”(按ISO 5218定义,可以参考它的标志符“SEX”,虽然这不是个好主意)。"sex_type"(动物或植物的生理选项:雄性还是雌性)或者“sex_frequency”(在我这一厢情愿的想法)。
可能最荒谬的错误是性质链。想下“type_code_id”什么意思。如果它是个标识,俺么在数据模型里它是唯一的并属于一个实体(想下"emp_id")。如果它是个代码,那么它有个外部的权威(想下“邮编”)。如果它是个类型,那对它有个测试(想下“血型”)。这就像没有一个名词来修改的一连串形容词。增加一个属性到链不会拯救含糊问题。
再次强调,基本规则是一个数据元名词告诉我们它是什么。名称不会告诉我们:
- 有表名的架构里它的位置
- 在特定表里它如何使用的(例如在名称里没有pk-,fk-或vw-等词缀的话)
- 它的数据如何物理存储的(例如对于整形、字符型等没有“i-”,“str-”等词缀)
- 没有告诉我们数据元不是什么。要确定并精确。
性质组件是从标准化列表里选取,你可以按需添加。这个列表成为你数据字典的一部分,并需要被执行。
在同个表里,当同样的数据元出现2个或更多的角色,要用到<角色>。例如,在组织报表里会有“supervisor_emp_id”和“subordinate_emp_id”,都来自Personnel表里的员工标识数据元“emp_id”。
来看下名称的长度。数据元名称太长或太短都不好。太短的名称很难理解,除非它是标准的缩写。它们也会模棱两可;我最喜欢的例子是一个系统,在数据元名称里有多个student的缩写方式,其中一个是“std”——经常会被误认为是“standard”的缩写,在有些地方甚至是“sexually transmitted disease(性病,由性交引起的病)”。
在名称里避免所有的特殊字符。坚持使用Latin-1字母,数字和下划线。它们会在其它程序语言里复用。没错,数据元名称不只为SQL。同样,避免同时使用仅微软支持的方括号“["或者仅ANSI/IOS支持的双引号标记。这个只是为在数据库里显示格式草率的编程完成,而不是前端显示。有一个可能的异常会是语言翻译问题,Latin-1字母不能正常工作。
执行大写规则来避免大小写敏感问题。我的规则是SQL 关键字是大写,标量数据元是小写,架构对象是大写。在我的《SQL 编程风格(Sql Programming Style )》书里有这方面的研究,但这里我会跳过细节。
对于数据元素名称的标准化性质后缀列表是基于Teradata的内部标准建立,在行业刊物上通用(CMP,MKP和其它出版商)。这些后缀有精确的含义。如果你需要发明你自己的,它们也要是精确的。
"_id"=标识者。在架构里它是唯一的,在架构里任何地方它指的是一个实体。唯一性和标识者不是同个东西。圆周率数字它是唯一的,但他不能标识一个实体。绝不使用“<表名>_id";这是基于位置的名字,并告诉你很可能这不是个真正的主键。简单的”id“太含糊,当你有无限个这样的名称,你就吧你的数据字典弄混。显然,自增长值也不是个标识。我一会谈下这个谬论。
"_date"或"_dt"=日期时间的维度。它是一些时间——工作,出生,终止等等。没有本身就是日期这样列名,那样会很糟糕,因为DATA在SQL里是注册的关键字。
"_nbr"或"_num"=标签数字;这是命名一些的数字字符。不要使用"_no",因为它看起来像布尔的是否值。我更喜欢"nbr"或"num",因为在多个欧洲语言里,它是常见的缩写,而且在"_num"里类似形状字母的组合会有视觉混淆。
"_name"或"_nm"=这是个字母名称本身就能看懂。它也成为名称量表。
"_code"或"_cd"=代码,被可信源,通常是企业外标准化维护的。例如,邮编是有米国邮政服务维护的。在它的上下文里,代码很好理解,因此你可能不需要翻译它。
"_size"=对于一个商品,例如衣服,鞋子, 信封或机器螺丝的行业标准或公司规模。
"_seq"=序列,序数。和标签数不是同个东西,因为它不会缺口。
"_tot"=合计,一个聚合的维度,逻辑上不同的部分。
"_tally"=值的个数,一个聚合的维度。也称为绝对标度。
"_status"=一个内部编码,反射了在知道的模式里将要修改的状态。考虑下军事地位。你会出生,然后改变状态到合法年龄。同时你不能和多个人结婚。你可以从已婚状态修改为离婚,从离婚变成已婚。如果你死了的话,就不能结婚。
"_cat"=分类,来自内部源的需要官方判定的编码。例如,五个飓风的类别。这不像个代码,需要这样的官方判定。
"_class"=不需要外部源的内部编码。一个类别就有一些共性一系列东西;对于动物分类你有规则,是哺乳还是爬行。有些情况你很难使用这些规则,例如在澳大利亚的哺乳动物,但是例外会变成它们自己的分类——单孔目。
"_type"=内外都有同样含义的编码。血型有新定义的测试过程。比起class,type通常更不正式,且会有重叠。type是三类中最弱的,它需要一个判断。在一些州,三轮摩托车是作为摩托车注册。在其它州,会作为汽车。在一些州,如果它有倒车档的话,也会作为汽车。
在实际的使用中,这3个方面会混淆。因此以行业标准来,即使它违反了上述的定义。
"_addr"或"_loc"=实体的地址或位置。地址和位置间有微妙的区别。地址可以指的是街道地址或一些外部的地理系统。位置指的是内部架构,例如仓库仓号。仓号可以保持一样,即使物理位置改变了。
"_img"=图片数据类型,例如.jpg, .gif等等。使用特定的格式作为性质会是重要的。
如果需要的话,可以随意添加。但记得跟踪并标准化你所做的。
原文链接:http://www.sqlservercentral.com/articles/Stairway+Series/69801/
数据库设计(1/9):数据元(Data Elements)的更多相关文章
- 数据元&数据字典&元数据
1. 数据元 data element(数据元素),单个数据单元,是数据的基本单位.参阅data field(数据字段). 2. 元数据 首先,我们举个例子来看看什么叫做“元”,在后现代主义文学中有一 ...
- Mysql之数据库设计
一.三大范式 1.第一范式:消除一个字段包含多个数据库值,消除一个记录包含重复的组(单独的一列包含多个项目),即可满足1NF. 2.第二范式:消除部分依赖性即可转化为2NF.部分依赖性表示一个记录中包 ...
- 基于web公交查询系统----数据库设计
要求:公交查询系统,管理员可以新增线路,修改车辆参数,发车时间表,删除车次,站名等. 用户可以按线路查询,按站点查询相关信息,也可查询两站点之间的换乘信息等. 数据库应包含管理员表,车站表,线路表,车 ...
- 大数据量查询优化——数据库设计、SQL语句、JAVA编码
数据库设计方面: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将 ...
- navicat data modeler的使用以及数据库设计的流程
E-R图(Entity Relationship Diagram) 又称实体-联系图 (提供了表示实体类型.属性和联系的方法,用来描述现实世界的概念模型) 构成E-R图的3个基本要素是实体型.属性和联 ...
- 数据库设计_ERMaster安装使用_PowerDesigner数据设计工具
数据库设计 1. 说在前面 项目开发的流程包括哪些环节 需求调研[需求调研报告]-- 公司决策层 (1) 根据市场公司需求分析公司是否需要开发软件来辅助日常工作 (2) 公司高层市场考察,市场分析,决 ...
- mySQL教程 第1章 数据库设计
E-R设计 很多同学在学SQL语句时,觉得非常困难,那是因为你在学一个你根本不了解的数据库,数据库中的表不是你设计的,表与表之间的关系你不明白.因此在学SQL语句之前,先介绍一下数据库设计. 下面举例 ...
- 数据库设计中的Soft Delete模式
最近几天有点忙,所以我们今天来一篇短的,简单地介绍一下数据库设计中的一种模式——Soft Delete. 可以说,该模式毁誉参半,甚至有非常多的人认为该模式是一个Anti-Pattern.因此在本篇文 ...
- 优化MySchool数据库设计之【巅峰对决】
优化MySchool数据库设计 之独孤九剑 船舶停靠在港湾是很安全的,但这不是造船的目的 By:北大青鸟五道口原玉明老师 1.学习方法: 01.找一本好书 初始阶段不适合,可以放到第二个阶段,看到知识 ...
随机推荐
- python获取当前时间的用法
1.先导入库:import datetime 2.获取当前日期和时间:now_time = datetime.datetime.now() 3.格式化成我们想要的日期:strftime() 比如:“2 ...
- ASP.NET Identity 2新增双重认证、帐号锁定、防伪印章功能并修复了一些bug
Microsoft最近发布了ASP.NET Identity 2,该版本支持双重认证.帐号锁定以及防伪印章功能,还增强了用户帐号和索引.此外新版本还包含一个改进的密码验证器并修复了一些bug. 借助于 ...
- MSDN杂志上Wix相关的文章
使用 MSBuild 和 Windows Installer XML 执行自动发布: http://msdn.microsoft.com/zh-cn/magazine/cc163456.aspx 用于 ...
- 用"hosting.json"配置ASP.NET Core站点的Hosting环境
通常我们在 Prgram.cs 中使用硬编码的方式配置 ASP.NET Core 站点的 Hosting 环境,最常用的就是 .UseUrls() . public class Program { p ...
- 《深入理解Java虚拟机》Java内存区域与内存溢出异常
注:“蓝色加粗字体”为书本原语 先来一张JVM运行时数据区域图,再接下来一一分析各区域功能: 程序计数器 程序计数器(program Counter Register)是一块较小的内存空间,它可以 ...
- MySQL mysqlslap压测
200 ? "200px" : this.width)!important;} --> 介绍 mysqlslap是mysql自带的一个性能压测工具:mysqlslap用于和其 ...
- Linux 服务器监控
200 ? "200px" : this.width)!important;} --> 标签:iostat/free/top/dstat 概述 文字主要讲述使用linux自带 ...
- [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题
[OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题 本文参考了(http://www.zeuscmd.com/tutorials/open ...
- Web前端开发大系概览 (前端开发技术栈)
前言 互联网建立50多年了,网站开发技术日新月异,但web前端始终离不开浏览器,最终还是HTML+JavaScript+CSS这3个核心,围绕这3个核心而开发出来大量技术框架/解决方案. 我从2000 ...
- 使用hexo搭建github.io博客(一)
使用github.io可以搭建一个自己的博客,把静态文件项目托管到github上,可以写博客,可以使用markdown语法,也可以展示作品.灵活性高.但是有较大的难度. node,git版本变化日新月 ...