DotNET企业架构应用实践-数据库表记录的唯一性设计的设计兼议主键设定原则
简要介绍
在我们进行数据库设计的时候,大家都会考虑到数据表主键的设计,而可能没有人去关注记录唯一性字段设计,或者说,很多开发人员把这两种混合在一起处理,即就是表记录的唯一性与主键相结合的技术,因为从本质上讲,表主键的值是必须唯一的,他即能确保表记录的唯一性。
我在本文提出的思路是分离表记录的唯一性与主表键的设计,也可以理解为是双主键的设计思路,即唯一性设计可以与表业务无关,而表主键的设计必须与业务相关联,一个主键记录一定能具有一定的业务意义。
主键设计的争议
关于数据库主键设计的一些原则与所采用的技术,园子中有大量的文章讨论,我选择两片具体代码性的文章,听棠.NET的数据库主键设计之思考和zhenyulu的小议数据库主键选取策略(原创)两篇文章。
关于数据库主键设计的一些原则与所采用的技术,园子中有大量的文章讨论,我选择两片具体代码性的文章,数据库主键设计之思考与小议数据库主键选取策略(原创)两篇文章。
在数据库主键设计之思考一文中,作者把数据库主键设计讲的很透彻,他也提出了主键设计与具体业务无关的论点:
“我强调主键不应该具有实际的意义,这可能对于一些朋友来说不太认同,比如订单表吧,会有“订单编号”字段,而这个字段呢在业务实际中本身就是应该具有唯一性,具有唯一标识记录的功能,但我是不推荐采用订单编号字段作为主键的,因为具有实际意义的字段,具有“意义更改”的可能性,比如订单编号在刚开始的时候我们一切顺利,后来客户说“订单可以作废,并重新生成订单,而且订单号要保持原订单号一致”,这样原来的主键就面临危险了。因此,具有唯一性的实际字段也代表可以作为主键。因此,我推荐是新设一个字段专门用为主键,此主键本身在业务逻辑上不体现,不具有实际意义。而这种主键在一定程序增加了复杂度,所以要视实际系统的规模大小而定,对于小项目,以后扩展不会很大的话,也查允许用实际唯一的字段作主键的。”
从个人的经历和技术角度来讲,我不同意这个主键与业务无意义的观点,我的观点是主键必须与业务相关,即一个表主键字段或者表主键字段组合必须具体一定的业务意义,并且增加一个与业务无关而有能确保记录唯一性的字段,即表的唯一性字段:
我列举一个例子,在商品进销存业务中的入库记录中记录个如下信息:
Ø dbo.PIN(产品入库表)
表名 |
PIN |
||
所有者 |
dbo |
||
列名 |
数据类型 |
空 |
说明 |
IDN |
INT |
Y |
ID |
BillCode |
VARCHAR(16) |
Y |
单根号 |
Code |
VARCHAR(16) |
Y |
产品编码 |
Name |
VARCHAR(128) |
Y |
产品名称 |
Spec |
VARCHAR(64) |
N |
规格 |
Unit |
VARCHAR(32) |
N |
单位 |
Price |
DECIMAL(18,4) |
Y |
价格 |
Number |
INT |
Y |
数量 |
Operator |
VARCHAR(64) |
Y |
入库员 |
InTime |
DATETIME |
N |
和库时间 |
业务要求同一入单可以包含1-N条产品库入库信息,同一入库单不得包含两条或条件以上的同一编码的商品记录,由此我们可以知道,入库单据号BillCode及产品编码Code即可以确定一笔交流,其组合是符合主键设立原则的,同时我们在主中增加了一个字段IDN,用于确保记录的唯一性。
相关的技术
表记录唯一性设计的技术我在本文不做详细的介绍,在数据库主键设计之思考与小议数据库主键选取策略(原创)两篇文章文章之中都有非常详细的论述,请大家去这两篇文章参考,他们建议这些技术使用于主键,而我更主张用于记录的唯一性确认上。
我推荐的选择
他多种唯一性确立技术之中,我比较喜欢“手动增长型字段”的设计,即在系统中增加一个表包含至少两个字段,Key和Value,如下所示:
Ø eas.IDENTITYVALUES(唯一值记录)
表名 |
IDENTITYVALUES |
||
所有者 |
eas |
||
列名 |
数据类型 |
空 |
说明 |
GUID |
UNIQUEIDENTIFIER |
N |
Guid |
ITEMKEY |
NVARCHAR(128) |
Y |
关键字 |
ITEMVALUE |
INT |
N |
当前值 |
DESCRIPTION |
NVARCHAR(256) |
N |
说明 |
同时,数据库中提供以下存储过程:
CREATE procedure eas.GetIdentityValue@itemKey char(128)ASBEGIN TRANSACTIONupdate eas.IDENTITYVALUES Set ITEMVALUE = ITEMVALUE + 1 where ITEMKEY = @itemKeyselect ITEMVALUE from eas.IDENTITYVALUES where ITEMKEY = @itemKeyCOMMIT TRANSACTIONGO
值可以采用整性或者长整性进行存储,在具体应用的过程之中,在应用表中增加一个字段,插入数据时取这个过程的返回值,如:
exec eas.GetIdentityValue @itemKey =“dbo.PIN”
数据分区的扩展
记录唯一性设计除了确保数据表记录的唯一性之外,还能为数据分区提供支持,不过这有一点要求,即唯一性设计必须采用整性或者并且一定连续意义的值才能处理,而如GUID这样的没有办法在将来支持扩展分区的设计。
本文先到此为止,在后面的文章中将会应用到这种技术并进行详细的讲解。
文未我加点广告,谢谢!
链接
一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录
AgileEAS.NET平台开发指南-系列目录
AgileEAS.NET应用开发平台介绍-文章索引
AgileEAS.NET平台应用开发教程-案例计划
AgileEAS.NET官方网站
敏捷软件工程实验室
QQ群:116773358(AgileEAS.NET平台)
DotNET企业架构应用实践-数据库表记录的唯一性设计的设计兼议主键设定原则相关推荐
- DotNET企业架构应用实践-系列目录
系列介绍 我一直在写关于AgileEAS.NET平台的一系列文章,也一直在推广AgileEAS.NET平台,本来也无意于独立的写这么一个系列,最早我是混杂在AgileEAS.NET平台中进行介绍的,即 ...
- DotNET企业架构应用实践-系统架构与性能-缓存技术与ORM中的缓存查询技术
系列回顾 在前面的文章DotNET企业架构应用实践-系统架构与性能-理论依据及相关做法一文中我介绍了系统性能优化的理论做了一个概括的介绍,也简单的介绍了性能优化的过程及相关的技术关注点或者说是做法. ...
- DotNET企业架构应用实践-企业管理软件架构(计算)的历史与发展(上)
企业管理软件是计算机软件应用的一个重要领域,在今天计算机软件除面向科学计算之外应用最广阔的也是企业管理应用,可以说计算机技术的发展推动着企业应用发展,企业管理需要也一方面影响着计算机技术的发展,今天, ...
- DotNET企业架构应用实践-企业管理软件架构的历史与发展(中)- 分布式系统
在前几天的DotNET企业架构应用实践-企业管理软件架构(计算)的历史与发展(上)一文中,介绍了在企业管理软件架构发布中的主机-终端结构.以及客户机-服务器结构.浏览器-服务器结构,本文今天向大家介绍 ...
- 转:DotNET企业架构应用实践-架构师成长之路-如何成为优秀架构师
来自:http://www.cnblogs.com/eastjade/archive/2010/10/25/1854621.html 前面写过几篇与架构相关的文章,后来呢也就有了这想一个简单的想法,把 ...
- mysql 核对_核对数据库表记录的shell脚本
项目中需要核对数据库表记录,由于表太多,一一核对是相当痛苦的事情,于是临时写了2个超级简单的脚本. 一个用来核对mysql数据库表的脚本,另外一个用来核对oracle数据库表的脚本. 有需要的朋友,可 ...
- MySQL数据库(3)_MySQL数据库表记录操作语句
附: MYSQL5.7版本sql_mode=only_full_group_by问题1.查询当前sql_mode: select @@sql_mode2.查询出来的值为:set @@sql_mode ...
- 在mysql中更新数据sql语句怎么写_在MySQL中,更新数据库表记录的SQL语句,包括______语句...
在MySQL中,更新数据库表记录的SQL语句,包括______语句 答:insert replace update delete 在域F中,设其特征为2,对于任意a,b∈F,则(a+b)2 等于多少 ...
- 数据库基础:什么是行?什么是主键?
表中的数据是按行存储的,所保存的每个记录存储在自己的行内. 如果将表想象为网格,网格中垂直的列为表列,水平行为表行.例如,顾客表可以每行存储一个顾客.表中的行数为记录的总数. 行(row) 表中的一个 ...
- mysql选择主键的原则_如何选择数据库的主键
我们现在在思考一下,应该采用什么来作表的主键比较合理,申明一下,主键的设计没有一个定论,各人有各人的方法,哪怕同一个,在不同的项目中,也会采用不同的主键设计原则. 第一:编号作主键 此方法就是采用实际 ...
最新文章
- html的body内标签之input系列1
- AMD透露Epyc服务器芯片更多细节 多方面挑战英特尔至强平台
- using namspace std的使用
- 孙剑亲自撰文:我在 Face++ 的这半年
- 【JavaMail-收取邮件】
- 使用php蓝天采集器抓取今日头条ajax的文章内容
- 史上最全MySQL 大表优化方案(长文)
- 辉哥给rockchip修复了一个内存溢出问题
- 树莓派安装python3.5_树莓派 | 04 安装基于python3.5的tensorflow,解决python版本不匹配问题...
- excel如何输入毫秒级时间
- [CTF]思维导向图
- python 数据结构面试_【Python排序面试题】面试问题:所谓数据结构,… - 看准网...
- python分页PDF
- 基于微信小程序的资产管理平台的设计与实现
- 10个优质PSD文件资源下载
- 开源Api后台服务/管理系统 HoServer
- vue 生成二维码海报并进行微信分享
- 用matlab画5日均线,用MATLAB求移动平均线,不用MOVAVG函数,求MA5,MA10 – MATLAB中文论坛...
- java使用knn实现mnist_java使用knn实现mnist - 百度学术
- 验证证书链 java_java实现证书链和签名验证
热门文章
- php5的程序如何安装在php7,centos安装php5和php7,并在apache里同时使用
- h5 右下角浮动按钮_Flutter 浮动按钮-FloatingActionButton的使用
- github进不去_app.gitbook.com进不去,一直卡着怎么回事
- Android中获取IMEI码及其它相关信息的源码
- SeasLog 之企业级日志行为规范发布
- CUDA编程优化(存储器访问优化,指令优化,参数优化,)
- 把路由器配置成DHCP服务器,并确保路由功能。
- 使用Inno Setup 打包.NET程序,并自动安装.Net Framework
- 03-4 BGP 默认路由/MED
- c语言A 100 开头地址,C语言库函数_-_A开头