数据库主键的故事
作者:李战 来源:软件真谛 发布时间:2008-05-31 07:50:00
1969年8月8日,在北京协和医院降生了一个漂亮的小女孩。接生的阿姨说,她的声音这么大,好象想要全世界的人都听到。
后来,她的父亲为她取了一个很好听的名字,叫“王菲”。于是,所有的小朋友就叫她“王菲”,“王菲”就是她童年的主键。
在她上初二的时候,认识了二班另一个叫“王菲”的同学,而且和她同一天生日。不过,同学们常常将她俩弄错,后来,就分别叫她们“大王菲”和“小王菲”。“大王菲”就是她在同学们心目中的主键。
在大王菲18岁的那一年,她领到了她的身份证。从此,她有了新的身份标识“100321690808022”,这一标识可以唯一区别中国大陆的每一个人。同时,原来二班的“小王菲”也领到了她自己的身份证,“100321690808006”。于是,人们就可以用身份证号,唯一标识两个“王菲”了。身份证号就是她成年后的主键。
由于她的歌唱的非常好,没多久就成了歌星。后来她去了香港发展,娱乐公司非要将她的名字更改为“王靖雯”,虽然她并不喜欢这个名字,但为了事业的发展还是同意了。“王靖雯”就成了她在娱乐圈里的主键。
“王靖雯”的歌打动了许许多多的歌迷,很快就成了歌坛天后。歌迷们将“王靖雯”这一主键与无数条动听的歌曲记录关联在了一起,并形成了一个庞大的歌迷数据库。
没多久,王靖雯和一个弹电吉他的小子相爱了。那小子说,还是“王菲”这个名字好听,于是,“王靖雯”又变回“王菲”了。主键被那小子修改了,这下麻烦大了。歌迷们都糊涂了,是将她的歌关联到“王菲”还是“王靖雯”呢?这一主键的修改,导致歌迷数据库的一次大混乱。
再后来呢,她和那个弹电吉他的小子结婚了,香港政府将他们的身份证号码,用结婚证书关联起来。这本也算一桩好事,可是,月老在酒醒之后发现了这一错误,就将关联的记录删除了。阴差阳错,命运使然,她和那个弹电吉他的小子只好分手了。
但是,正如接生的阿姨说的那样,她的声音的确让全世界的人都听到了!
讲完这个故事之后,我们是否能领悟到数据库设计的一些哲理呢?
什么是主键?
关系数据库说,为了唯一区分表的每一行记录,必须为表确定一个主键。主键可以是一个或多个列组成,这些主键列的值不能重复。主键是两个表进行关联的基础,所谓“关系”体现的是一个表的字段与另一个表的主键的关联。
在日常的应用项目开发中,我们常常都会面临“该拿什么字段来做主键”的难题。
用名字做主键?一班的“王菲”和二班的“王菲”可能重复。
用身份证号做主键?在大陆也许不会重复,去香港后,人家却不认。本不相信第二代身份证号会重复,但俺的一位同事正好撞上!
同样,主键值的更新也是麻烦事儿。“王靖雯”变成“王菲”那段日子,货架上一张唱片是王靖雯的,另一张又是王菲的,许多歌迷还以为又有新人出现了。
请不要说可以级联更新,将你那个做主键的字段加长两位试试?想当年,当身份证号从15位增加到18位时,给银行、证券、政府、企业...等多条战线上的兄弟们制造了怎样的痛苦啊!
为什么会出现这些问题呢?
原因就是:错误地把对象属性当作对象标识!
对象属性和对象标识都是对象数据库中的概念。
什么是对象属性呢?
就是业务逻辑上涉及的任何可变信息,什么“姓名”、“性别”、“身份证号”、“订单号”...通通都是对象属性。对象属性总会变化的,只是有些变得快,有些变得慢而已。
对象标识是啥?就是唯一区分数据对象的鉴别符,对象标识存在的唯一目的就是区分对象,除此之外没有任何业务逻辑上的意义。
不管王菲的属性值怎样变化,但王菲还是王菲,不是二班的那个“王菲”。也就是说,王菲的灵魂未变,她是不会改变的,就象哲学上所说的“不以人的意志为转移”。这种唯一表示对象本身的东西,就是对象标识!
对象标识是唯一的。也就是说,即使两个对象,他们的属性完全一样,但它们的对象标识是不同的。毕竟,同名同姓甚至同一天出生的大王菲和小王菲是两个不同的人。
对象的标识是永恒不变的。一旦对象产生,它的标识就自然地、唯一地产生了。尽管王菲换了名,身份证号也变过,但王菲的对象标识未变。即使到了下个世纪,她的对象标识也将依然存在于歌迷们的们的心中。
对象的标识是描述关系的基础。王菲唱的歌是王菲唱的,不是初二二班的那个“王菲”唱的。王靖雯唱的歌就是王菲唱的歌,有的歌迷只将歌曲和歌手的人名关联起来,难怪会出混乱。香港政府也犯相同的错误,将王菲的身份证号码这一内部属性,跟那个弹电吉他的小子关联起来,也许就是命运的错误。


猜你喜欢
- 1.什么是gRPCgRPC是rpc框架中的一种,是rpc中的大哥是一个高性能,开源和通用的RPC框架,基于Protobuf序列化协议开发,且
- 导读:这篇文章主要介绍如何利用opencv来对图像添加各类噪声,原图:1、高斯噪声高斯噪声就是给图片添加一个服从高斯分布的噪声,可以通过调节
- <script type="text/javascript"> var params&n
- 一般来说,通过c.Request.FormFile()获取文件的时候,所有内容都全部读到了内存。如果是个巨大的文件,则可能内存会爆掉;且,有
- 一、人脸图像特征提取方法https://www.jb51.net/article/219446.htm二、对笑脸数据集genki4k进行训练
- 改版背景创建专业的电子商务垂直搜索,以及把原有的信息聚合平台转型为在线采购批发交易平台。根据行业特点及交易需要,对原有的零批(小额批发)搜索
- 本文以Centos7.6系统与Oracle11g为例:一.先找到数据库的环境变量如果是在root账户下,须先登录到数据库所在账户su ora
- 开发动机:最近用手机QQ浏览器下载了一些视频,视频越来越多,占用了手机内存,于是想把下载的视频传到电脑上保存,可后来发现这些视频都是m3u8
- 写在前面:这次我主要想总结一下微信小程序实现上下滚动消息提醒,主要是利用swiper组件来实现,swiper组件在小程序中是滑块视图容器。我
- 目录MySQL数据库重命名的方法 第一种方法:rename database 弃用了第二种方法:mysqldump 备份第三种方法
- 服务器系统变量服务器将维护许多表示其配置的系统变量。所有变量均有默认值。可以在命令行中或选项文件设置选项在服务器启动时对它们进行设置。大多数
- Python版本 实现了比之前的xxftp更多更完善的功能1、继续支持多用户2、继续支持虚拟目录3、增加支持用户根目录以及映射虚拟目录的权限
- 6、遮罩滤镜作用:该滤镜可以为对象建立一个覆盖于表面的膜,其效果就象戴着有色眼镜看物体一样。语法: {filter:mask(color=c
- 本文实例为大家分享了python实现名片管理系统源代码,供大家参考,具体内容如下import osdef print_menu(): pri
- 一、基础环境准备windows环境:Pycharmpython3.6Django2.0.1Mysql5.7安装django 在pycharm
- 在Python中,经常会去读csv文件,如下import pandas as pdimport numpy as npdf = pd.rea
- 本文介绍了用ASP的AdoDb.Stream读取/写入UTF-8编码格式的文件的方法:函数名称:ReadTextFile 作用:利用AdoD
- 将有安全问题的SQL过程删除.比较全面.一切为了安全!删除了调用shell,注册表,COM组件的破坏权限MS SQL SERVER2000使
- 前言说到覆盖索引之前,先要了解它的数据结构:B+树。先建个表演示(为了简单,id按顺序建):idname1aa3kl5op8aa10kk11
- 前面文章分别简单介绍了线性回归,逻辑回归,贝叶斯分类,并且用python简单实现。这篇文章介绍更简单的 knn, k-近邻算法(kNN,k-