精华内容
下载资源
问答
  • 主关键字(PRIMARY KEY):主键中的一个或多个字段,它的值用于唯一地标识中的某一条记录。 外键(FOREIGN KEY):如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见...

    定义

    • 主关键字(PRIMARY KEY):主键是表中的一个或多个字段,它的值用于唯一地标识表中的某一条记录。

    • 外键(FOREIGN KEY):如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的相关联系。以另一个关系的外键作主关键字的表被称为主表,具有此外键的表被称为主表的从表。外键又称作外关键字。

    • 聚集索引:聚集索引是指数据库表行中数据的物理顺序与键值的逻辑(索引)顺序相同。一个表只能有一个聚集索引,因为一个表的物理顺序只有一种情况,所以,对应的聚集索引只能有一个。如果某索引不是聚集索引,则表中的行物理顺序与索引顺序不匹配,与非聚集索引相比,聚集索引有着更快的检索速度。

    • 非聚集索引:非聚集索引是一种索引,该索引中索引的逻辑顺序与磁盘上行的物理存储顺序不同。

    • 自动编号列和标识符列:对于每个表,均可创建一个包含系统生成的序号值的标识符列,该序号值以唯一方式标识表中的每一行。

    • 业务主键(自然主键):在数据库表中把具有业务逻辑含义的字段作为主键,称为“自然主键(Natural Key)”。

    • 逻辑主键(代理主键):在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,称为“代理主键”。

    • 复合主键(联合主键):通过两个或者多个字段的组合作为主键

    使用逻辑主键原因

    业务变化

    • 使用逻辑主键的主要原因是:业务主键一旦改变则系统中关联该主键部分的修改将会是不可避免的,并且引用越多改动越大。而使用逻辑主键则需要修改主键相关的业务逻辑即可,减少了业务主键相关改变对系统的影响。业务逻辑的改变是不可避免的,因为“永远不变是变化”,没有任何一个公司是一成不变的,没有任何一个业务是永远不变的。最典型的例子就是身份证升位和驾驶执照号换用身份证号的业务变更。而且现实中也确实出现了身份证号码重复的情况,这样如果用身份证号码作为主键也带来了难以处理的情况。当然应对改变,可以又很多解决方案,方案一是做一个新的系统与时俱进,这对软件公司说确实是好事。

    主键过大不利于传输、处理和存储

    • 使用逻辑主键的另外一个原因是,业务主键过大,不利于传输、处理和存储。我认为一般如果业务主键超过8字节就应该考虑使用逻辑主键了,因为int是4字节的,bigint是8字节的,而业务主键一般是字符串,同样是 8 字节的 bigint 和 8 字节的字符串在传输和处理上自然是 bigint 效率更高一些。想象一下 code == “12345678” 和 id == 12345678 的汇编码的不同就知道了。当然逻辑主键不一定是 int 或者 bigint ,而业务主键也不一定是字符串也可以是 int 或 datetime 等类型,同时传输的也不一定就是主键,这个就要具体分析了,但是原理类似,这里只是讨论通常情况。同时如果其他表需要引用该主键的话,也需要存储该主键,那么这个存储空间的开销也是不一样的。而且这些表的这个引用字段通常就是外键,或者通常也会建索引方便查找,这样也会造成存储空间的开销的不同,这也是需要具体分析的。
    • 使用逻辑主键的再一个原因是,使用 int 或者 bigint 作为外键进行联接查询,性能会比以字符串作为外键进行联接查询快。原理和上面的类似,这里不再重复。

    人为因素

    • 使用逻辑主键的再一个原因是,存在用户或维护人员误录入数据到业务主键中的问题。例如错把 RMB 录入为 RXB ,相关的引用都是引用了错误的数据,一旦需要修改则非常麻烦。如果使用逻辑主键则问题很好解决,如果使用业务主键则会影响到其他表的外键数据,当然也可以通过级联更新方式解决,但是不是所有都能级联得了的。

    使用业务主键的原因

    • 使用业务主键的主要原因是,增加逻辑主键就是增加了一个业务无关的字段,而用户通常都是对于业务相关的字段进行查找(比如员工的工号,书本的 ISBN No. ),这样我们除了为逻辑主键加索引,还必须为这些业务字段加索引,这样数据库的性能就会下降,而且也增加了存储空间的开销。所以对于业务上确实不常改变的基础数据而言,使用业务主键不失是一个比较好的选择。另一方面,对于基础数据而言,一般的增、删、改都比较少,所以这部分的开销也不会太多,而如果这时候对于业务逻辑的改变有担忧的话,也是可以考虑使用逻辑主键的,这就需要具体问题具体分析了。

    安全问题

    • 使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需求并不是出于性能的考虑而是出于安全性的考虑。
    • 使用业务主键的另外一个原因是,对于用户操作而言,都是通过业务字段进行的,所以在这些情况下,如果使用逻辑主键的话,必须要多做一次映射转换的动作。我认为这种担心是多余的,直接使用业务主键查询就能得到结果,根本不用管逻辑主键,除非业务主键本身就不唯一。另外,如果在设计的时候就考虑使用逻辑主键的话,编码的时候也是会以主键为主进行处理的,在系统内部传输、处理和存储都是相同的主键,不存在转换问题。除非现有系统是使用业务主键,要把现有系统改成使用逻辑主键,这种情况才会存在转换问题。暂时没有想到还有什么场景是存在这样的转换的。
    • 使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需求并不是出于性能的考虑而是出于安全性的考虑。
    • 使用复合主键的主要原因和使用业务主键是相关的,通常业务主键只使用一个字段不能解决问题,那就只能使用多个字段了。例如使用姓名字段不够用了,再加个生日字段。这种使用复合主键方式效率非常低,主要原因和上面对于较大的业务主键的情况类似。另外如果其他表要与该表关联则需要引用复合主键的所有字段,这就不单纯是性能问题了,还有存储空间的问题了,当然你也可以认为这是合理的数据冗余,方便查询,但是感觉有点得不偿失。
    • 使用复合主键的另外一个原因是,对于关系表来说必须关联两个实体表的主键,才能表示它们之间的关系,那么可以把这两个主键联合组成复合主键即可。如果两个实体存在多个关系,可以再加一个顺序字段联合组成复合主键,但是这样就会引入业务主键的弊端。当然也可以另外对这个关系表添加一个逻辑主键,避免了业务主键的弊端,同时也方便其他表对它的引用。
    • 综合来说,网上大多数人是倾向于用逻辑主键的,而对于实体表用复合主键方式的应该没有多少人认同。支持业务主键的人通常有种误解,认为逻辑主键必须对用户来说有意义,其实逻辑主键只是系统内部使用的,对用户来说是无需知道的。

    结论或推论:

    1、尽量避免使用业务主键,尽量使用逻辑主键。

    2、如果要使用业务主键必须保证业务主键相关的业务逻辑改变的概率为0,并且业务主键不太大,并且业务主键不能交由用户修改。

    3、除关系表外,尽量不使用复合主键。

    (想自学习编程的小伙伴请搜索圈T社区,更多行业相关资讯更有行业相关免费视频教程。完全免费哦!)

    展开全文
  • **about业务主键和逻辑主键 1业务主键(natrual key),有意义的字段。 对前端可见2逻辑主键(surrogate key),无意义的字段,即自增长字段,即identity。这其中还有一个选择GUID。 如果有业务主键,数据唯一性就能...

     

    **about业务主键和逻辑主键

    1业务主键(natrual key),有意义的字段。 对前端可见
    2逻辑主键(surrogate key),无意义的字段,即自增长字段,即identity。这其中还有一个选择GUID。

    如果有业务主键,数据唯一性就能得到保证,逻辑主键存在的意义?
    尽量不要用GUID作 PRIMARY KEY.
    PRIMARY KEY可以用多列,不一定非要使用以列

    以下是一些反对用逻辑主键的理由,
    --
    1.They 're not standard SQL. Most products have it but there 's no consistent implementation.
    2.They can 't be updated. This violates the relational data model (not fatal, but not good either). Duplicates can be accidentally inserted (fatal).
    3.They only create numeric values. GUID/NewID() are also numeric only, and are hard to read.
    4.Numeric values are not meaningful in many tables, and adding them complicates relationships between other tables.
    --
    Problems such as supporting replication, merging, and a providing a limited number of unique values for a heavy transactional systems
    --
    IDENTITY字段不要作为表的主键与其它表关联,这将会影响到该表的数据迁移。
    --

     

    *viewPoint01

    既然有业务主键,数据唯一性就能得到保证了。 
    那么你的逻辑主键的存在的意义或者是目的是什么呢? 
    逻辑主键的存在的意义在于当业务主键是多个字段组合的和/或业务主键的数据类型不便于比较的时候,用业务主键作为聚集索引影响性能,这个时候加一个冗余的数字型的逻辑主键显得很必要,也会方便编程。 
    加逻辑主键应该主要是从性能考虑

     

    *viewPoint02

    我有不同的观点: 
    我认为业务主键作为聚集索引反而更有利,因为在大数量的业务操作中,操作员能记住并交流的的就只有那么几个有限的数据:业务单据号、物品编号(名称)、客户编号(名称)。他们在查询的时候最多就是这些,最多还要加上日期时间。数据库查询的压力都来自他们。所以应该说好处是比较大的。 
    说到这里,我还要说个题外话。除开WEB的设计方式来讲,企业的关键数据是不允许出现很多人在这里问的要怎么删除重复数据的情况的。不是完全不能,只是回给大家带来很多困扰,影响后面的流程。 
    话说回来,一个逻辑主键与一业务主键共存的数据集用哪个来与外界联系?都可以! 
    那么逻辑主键不是流水号,每个表都有1和10,困扰也很大。

     

    *viewPoint03

    其实我觉得比较好的是两种方法都用。 

    最好是业务主键做为聚集索引,identity做唯一索引。 

    identity并不适合做为聚集索引,因为   identity若做为聚集索引,性能不好(虽然我自己也没感觉到)。用identity做为聚集索引,会造成局部热点,也是就某个存储区域过热,这样会造成大量的操作都在相邻的存储区域进行,会对性能造成影响。理论上我觉得是很有道理的,不过实际上我没有什么体会。 

    业务主键做为聚集索引,会对查询性能有很多好处。 

     

     

    *viewPoint04

    “既然有业务主键,数据唯一性就能得到保证了” 

    引入   Identity,GUID   的原因就是业务主键的唯一性很难保证,因为自然主键来自实际业务,往往是人工编制而成,其唯一性不容易得到保证。 

    Identity   作主键,除了唯一性可以保证以外,还可以提高索引的速度,因为对索引而言,   INT   数据类型的   Identity   的速度是最快的。

    但我也很喜欢用identity(或无意义的关键字),因为在做程序时,用一个integer做为参数就可以了,不必用几个参数,而且也方便移值给其它表或其它系统使用。用identity也有它的好处。 

    至于复制,如果要考虑分发复制的话,我觉得不必怪罪到identity头上,你大可以用业务主键来做复制,为什么要用identity?

     

    *viewPoint05

    其实我在WEB开发的时候就是会用Identity做主键的,感觉比较爽。 
    但是换过来我在做企业管理软件的时候就是采用‘自定义’业务主键了。所谓自定义就是在一开始由用户定义一个格式比如,长度,打头字母,起始编号等,当然这个编号最后还是依据用户定义自增长的。所以从来都没有出现过主键重复过:) 
    而且用户也乐意使用这样的业务主键。

     

    *viewPoint06

    对老外的话(他是逻辑主键的反对方),我觉的他说的可能是这种情况(当然各位可能已经理解了):   
    当手工合并两张表时,这两张表的IDENTITY字段很可能都是1,2,3,4,5........,这样问题出现了,主键不唯一,首先你需要重建IDENTITY来保证主键唯一,另外引用他们的外键全得修改。   

    坛子里我想有很多人都认为该用逻辑主键,但象上面这种情况各位是否考虑过?处理过? 
    更棘手的问题: 
    几个分公司的全部数据(其中有很多父子表),定时发送到总公司。分公司、总公司表结构一样,只要用到IDENTITY,真的很麻烦了...

     

    *viewPoint07

    我以前经常处理这样的表,只要头脑清楚就行了。麻烦是麻烦了一点,但谁会天天去倒数据呢? 

    总公司和分公司的情况,你可以另加一个字段branchID,用branchID   +   ID做为唯一键。 

    用identity的一些好处也是有的,比如做三层结构的设计时,不同的单据共用相同的对象模型或公用函数,但不同的单据的业务关键字都不一样,就会很不好做统一的接口,用identity则所有的单据都只用ID做为参数就可以了,问题迎刃而解。 

    所以用不用,可以按实际情况决定取舍。

    A:icevi(按钮工厂)   前面不是说了一个方法了吗,就是加上一个表示分支的branchID。用branchID+IDENTITY组合成合并表的主键。

     

    *viewPoint08

    用identity确实有些问题,首先是合并复制问题。 
    MS给出3种方案: 
    1Automatic   Identity   Range   Handling。 
    2Manual   Identity   Range   Handling。即NOT   FOR   REPLICATION   。 
    3Using   Other   Columns   as   Primary   Keys。这第3种方案即icevi(按钮工厂)所说的方法。 

    我现在的问题:这3种方法中,各位认为第3种方案是最好的吗?只是觉得有些麻烦,每个有INDENTITY的表都得有个BranchID;如果我每个表都有IDENTITY,编码时,每一次增,删,改,查都要跟上BranchID,噩梦? 

    因为公司业务经常是无法预见的,开发时还是一个公司,两年后,可能全国各地好多子公司,按着这种思路,开发之初就应该加BranchID。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    定义(部分定义来源于 SQL Server 联机丛书):

    主键(PRIMARY KEY):表通常具有包含唯一标识表中每一行的值的一列或一组列。这样的一列或多列称为表的主键 (PK),用于强制表的实体完整性。

    外键(FOREIGN KEY):外键 (FK) 是用于建立和加强两个表数据之间的链接的一列或多列。在外键引用中,当一个表的列被引用作为另一个表的主键值的列时,就在两表之间创建了链接。这个列就成为第二个表的外键。

    聚集索引:聚集索引基于数据行的键值在表内排序和存储这些数据行。每个表只能有一个聚集索引,因为数据行本身只能按一个顺序存储。

    非聚集索引:非聚集索引包含索引键值和指向表数据存储位置的行定位器。可以对表或索引视图创建多个非聚集索引。通常,设计非聚集索引是为改善经常使用的、没有建立聚集索引的查询的性能。

    自动编号列和标识符列:对于每个表,均可创建一个包含系统生成的序号值的标识符列,该序号值以唯一方式标识表中的每一行。

    业务主键(自然主键):在数据库表中把具有业务逻辑含义的字段作为主键,称为“自然主键(Natural Key)”。

    逻辑主键(代理主键):在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,称为“代理主键”。

    复合主键(联合主键):通过两个或者多个字段的组合作为主键。

     

    原理分析:

    使用逻辑主键的主要原因是,业务主键一旦改变则系统中关联该主键的部分的修改将会是不可避免的,并且引用越多改动越大。而使用逻辑主键则只需要修改相应的业务主键相关的业务逻辑即可,减少了因为业务主键相关改变对系统的影响范围。业务逻辑的改变是不可避免的,因为“永远不变的是变化”,没有任何一个公司是一成不变的,没有任何一个业务是永远不变的。最典型的例子就是身份证升位和驾驶执照号换用身份证号的业务变更。而且现实中也确实出现了身份证号码重复的情况,这样如果用身份证号码作为主键也带来了难以处理的情况。当然应对改变,可以有很多解决方案,方案之一是做一新系统与时俱进,这对软件公司来说确实是件好事。

    使用逻辑主键的另外一个原因是,业务主键过大,不利于传输、处理和存储。我认为一般如果业务主键超过8字节就应该考虑使用逻辑主键了,因为int是4字节的,bigint是8字节的,而业务主键一般是字符串,同样是 8 字节的 bigint 和 8 字节的字符串在传输和处理上自然是 bigint 效率更高一些。想象一下 code == "12345678" 和 id == 12345678 的汇编码的不同就知道了。当然逻辑主键不一定是 int 或者 bigint ,而业务主键也不一定是字符串也可以是 int 或 datetime 等类型,同时传输的也不一定就是主键,这个就要具体分析了,但是原理类似,这里只是讨论通常情况。同时如果其他表需要引用该主键的话,也需要存储该主键,那么这个存储空间的开销也是不一样的。而且这些表的这个引用字段通常就是外键,或者通常也会建索引方便查找,这样也会造成存储空间的开销的不同,这也是需要具体分析的。

    使用逻辑主键的再一个原因是,使用 int 或者 bigint 作为外键进行联接查询,性能会比以字符串作为外键进行联接查询快。原理和上面的类似,这里不再重复。

    使用逻辑主键的再一个原因是,存在用户或维护人员误录入数据到业务主键中的问题。例如错把 RMB 录入为 RXB ,相关的引用都是引用了错误的数据,一旦需要修改则非常麻烦。如果使用逻辑主键则问题很好解决,如果使用业务主键则会影响到其他表的外键数据,当然也可以通过级联更新方式解决,但是不是所有都能级联得了的。

    使用业务主键的主要原因是,增加逻辑主键就是增加了一个业务无关的字段,而用户通常都是对于业务相关的字段进行查找(比如员工的工号,书本的 ISBN No. ),这样我们除了为逻辑主键加索引,还必须为这些业务字段加索引,这样数据库的性能就会下降,而且也增加了存储空间的开销。所以对于业务上确实不常改变的基础数据而言,使用业务主键不失是一个比较好的选择。另一方面,对于基础数据而言,一般的增、删、改都比较少,所以这部分的开销也不会太多,而如果这时候对于业务逻辑的改变有担忧的话,也是可以考虑使用逻辑主键的,这就需要具体问题具体分析了。

    使用业务主键的另外一个原因是,对于用户操作而言,都是通过业务字段进行的,所以在这些情况下,如果使用逻辑主键的话,必须要多做一次映射转换的动作。我认为这种担心是多余的,直接使用业务主键查询就能得到结果,根本不用管逻辑主键,除非业务主键本身就不唯一。另外,如果在设计的时候就考虑使用逻辑主键的话,编码的时候也是会以主键为主进行处理的,在系统内部传输、处理和存储都是相同的主键,不存在转换问题。除非现有系统是使用业务主键,要把现有系统改成使用逻辑主键,这种情况才会存在转换问题。暂时没有想到还有什么场景是存在这样的转换的。

    使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需求并不是出于性能的考虑而是出于安全性的考虑。

    使用复合主键的主要原因和使用业务主键是相关的,通常业务主键只使用一个字段不能解决问题,那就只能使用多个字段了。例如使用姓名字段不够用了,再加个生日字段。这种使用复合主键方式效率非常低,主要原因和上面对于较大的业务主键的情况类似。另外如果其他表要与该表关联则需要引用复合主键的所有字段,这就不单纯是性能问题了,还有存储空间的问题了,当然你也可以认为这是合理的数据冗余,方便查询,但是感觉有点得不偿失。

    使用复合主键的另外一个原因是,对于关系表来说必须关联两个实体表的主键,才能表示它们之间的关系,那么可以把这两个主键联合组成复合主键即可。如果两个实体存在多个关系,可以再加一个顺序字段联合组成复合主键,但是这样就会引入业务主键的弊端。当然也可以另外对这个关系表添加一个逻辑主键,避免了业务主键的弊端,同时也方便其他表对它的引用。

    综合来说,网上大多数人是倾向于用逻辑主键的,而对于实体表用复合主键方式的应该没有多少人认同。支持业务主键的人通常有种误解,认为逻辑主键必须对用户来说有意义,其实逻辑主键只是系统内部使用的,对用户来说是无需知道的。

     

    结论或推论:

    1、尽量避免使用业务主键,尽量使用逻辑主键。

    2、如果要使用业务主键必须保证业务主键相关的业务逻辑改变的概率为0,并且业务主键不太大,并且业务主键不能交由用户修改。

    3、除关系表外,尽量不使用复合主键。

     

    使用逻辑主键的最佳实践指南:

    1、足够用就好。系统使用的生命周期以100年为限,逻辑主键数据类型采用下表规则,如果不确定则使用int类型。

    数据量 数据类型 数据大小 生成频率 备注
    < 128 tinyint 1 字节 1条/年 频率过低,不太靠谱,不建议采用
    < 3 万 smallint 2 字节 27条/月 频率较低,慎用
    < 21 亿 int 4 字节 40条/分钟 能满足大部分情况
    < 922 亿亿 bigint 8 字节 292万条/毫秒 能满足绝大部分情况 
    >= 922 亿亿 uniqueidentifier 16 字节

    100亿用户同时每毫秒生成10亿条,可以连续生成10亿年

    可用于分布式、高并发的应用

    2、一般采用自增长方式或NewID()方式。

    3、主键字段名称一般采用“表名ID”方式,方便识别和表联接。

    4、如果表存在分布式应用,则可以考虑采用不同起始值,相同步长方式自增。例如有3个部署在不同地方的库,则可以如下设计:

    起始值 步长
    1 10
    2 10
    3 10

    步长统一设置10是为了方便日后扩展,这样不同库之间也能保持主键唯一性了,也方便合并。

    5、如果存在高并发性需求或数据表迁移需求,可以考虑使用uniqueidentifier类型,并使用NewID()函数。

    6、可以考虑对业务主键建立唯一性索引,以实现业务主键唯一性的业务需求。

    7、如果需要考虑业务主键的性能需求,可以把业务主键建立聚集索引,而逻辑主键只建立主键约束和非聚集索引即可。

    8、关系表可以考虑采用复合主键方式,复合主键不用于实体表。

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    *viewPoint09

     1、从纯数据库设计的角度来看: 
    使用业务主键是自然的选择,但如果业务发生变化引起业务主键的变化怎么办?(xiaoyu举的例子),所以引入逻辑主键id(当然不是每张表都要),浪费空间之说我认为是没有必要考虑的,存储技术的发展能容忍这点小浪费。而且单一的id在多表关联时,显然比复合主键有更好的性能。 
    2、从WEB应用开发的角度来看: 
    用逻辑主键你只需要在页面和后台之间传递一个单一的参数,简化了开发工作,而且有较高的查询效率。 
    3、从Hibernate应用的角度来说: 
    复合主键需要更多的处理,性能不高,所以Hibernate不提倡用复合主键

     

     

     

     

    转载于:https://www.cnblogs.com/LIS2011/archive/2012/10/31/2748001.html

    展开全文
  • 2.使用自增主键的场景:a:中找不出3个以内字段可以表示的业务主键b:没有集中大量的插入操作c:不使用自增id作为外键(即id变化不影响系统逻辑和功能)此外自增主键的规律很明显,为了不让别...

    主键的设置方法有3种:

    一种是设置自增长主键,第二种是采用业务主键,第三种是生成唯一序列(使用uuid/guid);

    如何选择主键设置方式:

    1.主键的使用目的:

    a.为了保证数据查找唯一;

    b.提高存储效率和索引效率。

    2.使用自增主键的场景:

    a:表中找不出3个以内字段可以表示的业务主键

    b:没有集中大量的插入操作

    c:不使用自增id作为外键(即id变化不影响系统逻辑和功能)

    此外自增主键的规律很明显,为了不让别人轻易的采集数据,同时符合以上条件,则优先选择自增主键;

    3.使用业务主键做id:

    a.如果你设计的表上存在非重复数据列,且常以该列检索数据,或该列还关联其他表的外键,譬如学号、会员卡号、身份证号这些,可以用来做为主键,主键在默认设置下      是聚集索引,这样检索学号、卡号这些效率上就会比较高。

    4.使用生成唯一的序列

    a.如果不满足使用自增的要求,则建议优先使用字符主键。类似网站数据库,可以采用uuid、guid这类无规则字符做主键。因为字符主键查询速度不比自增主键慢。

    b.考虑自增主键的弊端。很多表的ID会被其他表引用为外键,而且自增主键弊端是,用DELETE删除后,不会从新接着自增,而是接着删除前的ID自增;在多数据库迁移          下,自增则会很繁琐,需要另外做联合主键才能保证数据的唯一性。

    展开全文
  • 逻辑主键业务主键

    千次阅读 2016-03-10 22:21:31
    逻辑主键业务主键@(数据库)[笔记|2016.03.10]逻辑主键业务主键 逻辑主键 业务主键 总结 提示对逻辑主键、业务主键和复合主键的思考 —— 资料来源 逻辑主键存在用户或维护人员误录入数据到业务主键中的问题...

    逻辑主键 与 业务主键

    @(数据库)[笔记|2016.03.10]

    • 对逻辑主键、业务主键和复合主键的思考 —— 资料来源

    逻辑主键

    存在用户或维护人员误录入数据到业务主键中的问题。例如错把 RMB 录入为 RXB ,相关的引用都是引用了错误的数据,一旦需要修改则非常麻烦。如果使用逻辑主键则问题很好解决,如果使用业务主键则会影响到其他表的外键数据,当然也可以通过级联更新方式解决,但是不是所有都能级联得了的。

    业务主键

    使用业务主键的主要原因是,增加逻辑主键就是增加了一个业务无关的字段,而用户通常都是对于业务相关的字段进行查找(比如员工的工号,书本的 ISBN No. ),这样我们除了为逻辑主键加索引,还必须为这些业务字段加索引,这样数据库的性能就会下降,而且也增加了存储空间的开销。所以对于业务上确实不常改变的基础数据而言,使用业务主键不失是一个比较好的选择。

    另一方面,对于基础数据而言,一般的增、删、改都比较少,所以这部分的开销也不会太多,而如果这时候对于业务逻辑的改变有担忧的话,也是可以考虑使用逻辑主键的.

    如果使用逻辑主键的话,必须要多做一次映射转换的动作。我认为这种担心是多余的,直接使用业务主键查询就能得到结果,根本不用管逻辑主键,除非业务主键本身就不唯一。另外,如果在设计的时候就考虑使用逻辑主键的话,编码的时候也是会以主键为主进行处理的,在系统内部传输、处理和存储都是相同的主键,不存在转换问题。除非现有系统是使用业务主键,要把现有系统改成使用逻辑主键,这种情况才会存在转换问题。暂时没有想到还有什么场景是存在这样的转换的。

    业务主键场景

    使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需求并不是出于性能的考虑而是出于安全性的考虑。

    总结

    综合来说,网上大多数人是倾向于用逻辑主键的,而对于实体表用复合主键方式(跳过)的应该没有多少人认同。支持业务主键的人通常有种误解,认为逻辑主键必须对用户来说有意义,其实逻辑主键只是系统内部使用的,对用户来说是无需知道的
    - 尽量避免使用业务主键,尽量使用逻辑主键。
    - 如果要使用业务主键必须保证业务主键相关的业务逻辑改变的概率为0,并且业务主键不太大,并且业务主键不能交由用户修改。
    - 除关系表外,尽量不使用复合主键。

    提示

    使用逻辑主键的最佳实践指南:
    1. 足够用就好。系统使用的生命周期以100年为限,逻辑主键数据类型采用下表规则,如果不确定则使用int类型。

    数据量 数据类型 数据大小 生成频率 备注
    < 128 tinyint 1 字节 1条/年 频率过低,不太靠谱,不建议采用
    < 3 万 smallint 2 字节 27条/月 频率较低,慎用
    < 21 亿 int 4 字节 40条/分钟 能满足大部分情况
    < 922 亿亿 bigint 8 字节 292万条/毫秒 能满足绝大部分情况
    = 922 亿亿
    uniqueidentifier 16 字节 100亿用户同时每毫秒生成10亿条,可以连续生成10亿年 可用于分布式、高并发的应用

    2. 一般采用自增长方式或NewID()方式。
    3. 主键字段名称一般采用“表名ID”方式,方便识别和表联接。
    4. 如果表存在分布式应用,则可以考虑采用不同起始值,相同步长方式自增。例如有3个部署在不同地方的库,则可以如下设计:
    起始值 步长
    1 10
    2 10
    3 10
    步长统一设置10是为了方便日后扩展,这样不同库之间也能保持主键唯一性了,也方便合并。
    5. 如果存在高并发性需求或数据表迁移需求,可以考虑使用uniqueidentifier类型,并使用NewID()函数。
    6. 可以考虑对业务主键建立唯一性索引,以实现业务主键唯一性的业务需求。
    7. 如果需要考虑业务主键的性能需求,可以把业务主键建立聚集索引,而逻辑主键只建立主键约束和非聚集索引即可。
    8. 关系表可以考虑采用复合主键方式,复合主键不用于实体表。

    逻辑主键 与 业务主键

    逻辑主键 与 业务主键
    逻辑主键
    业务主键
    总结
    提示
    对逻辑主键、业务主键和复合主键的思考 —— 资料来源
    逻辑主键

    存在用户或维护人员误录入数据到业务主键中的问题。例如错把 RMB 录入为 RXB ,相关的引用都是引用了错误的数据,一旦需要修改则非常麻烦。如果使用逻辑主键则问题很好解决,如果使用业务主键则会影响到其他表的外键数据,当然也可以通过级联更新方式解决,但是不是所有都能级联得了的。

    业务主键

    使用业务主键的主要原因是,增加逻辑主键就是增加了一个业务无关的字段,而用户通常都是对于业务相关的字段进行查找(比如员工的工号,书本的 ISBN No. ),这样我们除了为逻辑主键加索引,还必须为这些业务字段加索引,这样数据库的性能就会下降,而且也增加了存储空间的开销。所以对于业务上确实不常改变的基础数据而言,使用业务主键不失是一个比较好的选择。

    另一方面,对于基础数据而言,一般的增、删、改都比较少,所以这部分的开销也不会太多,而如果这时候对于业务逻辑的改变有担忧的话,也是可以考虑使用逻辑主键的.
    如果使用逻辑主键的话,必须要多做一次映射转换的动作。我认为这种担心是多余的,直接使用业务主键查询就能得到结果,根本不用管逻辑主键,除非业务主键本身就不唯一。另外,如果在设计的时候就考虑使用逻辑主键的话,编码的时候也是会以主键为主进行处理的,在系统内部传输、处理和存储都是相同的主键,不存在转换问题。除非现有系统是使用业务主键,要把现有系统改成使用逻辑主键,这种情况才会存在转换问题。暂时没有想到还有什么场景是存在这样的转换的。

    业务主键场景

    使用业务主键的再一个原因是,对于银行系统而言安全性比性能更加重要,这时候就会考虑使用业务主键,既可以作为主键也可以作为冗余数据,避免因为使用逻辑主键带来的关联丢失问题。如果由于某种原因导致主表和子表关联关系丢失的话,银行可是会面临无法挽回的损失的。为了杜绝这种情况的发生,业务主键需要在重要的表中有冗余存在,这种情况最好的处理方式就是直接使用业务主键了。例如身份证号、存折号、卡号等。所以通常银行系统都要求使用业务主键,这个需求并不是出于性能的考虑而是出于安全性的考虑。

    总结

    综合来说,网上大多数人是倾向于用逻辑主键的,而对于实体表用复合主键方式(跳过)的应该没有多少人认同。支持业务主键的人通常有种误解,认为逻辑主键必须对用户来说有意义,其实逻辑主键只是系统内部使用的,对用户来说是无需知道的

    尽量避免使用业务主键,尽量使用逻辑主键。
    如果要使用业务主键必须保证业务主键相关的业务逻辑改变的概率为0,并且业务主键不太大,并且业务主键不能交由用户修改。
    除关系表外,尽量不使用复合主键。
    提示

    使用逻辑主键的最佳实践指南:

    足够用就好。系统使用的生命周期以100年为限,逻辑主键数据类型采用下表规则,如果不确定则使用int类型。
    数据量 数据类型 数据大小 生成频率 备注
    < 128 tinyint 1 字节 1条/年 频率过低,不太靠谱,不建议采用
    < 3 万 smallint 2 字节 27条/月 频率较低,慎用
    < 21 亿 int 4 字节 40条/分钟 能满足大部分情况
    < 922 亿亿 bigint 8 字节 292万条/毫秒 能满足绝大部分情况
    = 922 亿亿 uniqueidentifier 16 字节 100亿用户同时每毫秒生成10亿条,可以连续生成10亿年 可用于分布式、高并发的应用
    一般采用自增长方式或NewID()方式。
    主键字段名称一般采用“表名ID”方式,方便识别和表联接。
    如果表存在分布式应用,则可以考虑采用不同起始值,相同步长方式自增。例如有3个部署在不同地方的库,则可以如下设计:
    起始值 步长
    1 10
    2 10
    3 10
    步长统一设置10是为了方便日后扩展,这样不同库之间也能保持主键唯一性了,也方便合并。
    如果存在高并发性需求或数据表迁移需求,可以考虑使用uniqueidentifier类型,并使用NewID()函数。
    可以考虑对业务主键建立唯一性索引,以实现业务主键唯一性的业务需求。
    如果需要考虑业务主键的性能需求,可以把业务主键建立聚集索引,而逻辑主键只建立主键约束和非聚集索引即可。
    关系表可以考虑采用复合主键方式,复合主键不用于实体表。
    1695
    93863158
    退出账号
    当前文档
    恢复至上次同步状态
    删除文档
    导出…
    预览文档
    分享链接
    系统
    设置
    下载桌面客户端
    下载离线Chrome App
    使用说明
    快捷帮助
    常见问题
    关于

    逻辑主键 与 业务主键
    欢迎使用马克飞象
    我的第一个笔记本 Git
    我的第一个笔记本 API文档

    展开全文
  • 关于业务主键和逻辑主键

    千次阅读 2017-11-03 22:00:52
    业务主键(自然主键):在数据库表中把具有业务逻辑含义的字段作为主键,称为“自然主键(Natural Key)”。 逻辑主键(代理主键):在数据库表中采用一个与当前表中逻辑信息无关的字段作为其主键,称为“代理主键...
  • 关于数据库表主键设计,一般而言,是根据业务需求情况,以业务逻辑为基础,形成主键。 比如,销售时要记录销售情况,一般需要两个表,一个是销售单的概要描述,记录诸如销售单号、总金额一类的情况,另外一个表...
  • 原有的数据库表的设计中,很多表中都是用了联合主键 ,因为这样的设计符合业务上的概念,而且原生的jdbc数据库访问也不存在使用联合主键的困难。 但是,现在一切变了,一方面,我们享受者hibernate的面向对象的变量...
  • 逻辑主键还是业务主键

    千次阅读 2004-11-07 23:54:00
    今天在javaeye上看了一篇关于数据库设计的文章...主张逻辑主键的人用身份证号码升级分部数据汇总到总部的例子来说明业务主键无法做到永远不变,主张每个最好还是建一个逻辑主键才能够解决问题,虽然关联查询的时候
  • 一、前言 在项目开发中往往会遇到两个实体对象之间存在多对多关系的情况,此时我们会维护两个实体对象,一个关系,用来存放两者之间...如下图所示:,业务逻辑就是一个学生只能有当前课程的一个分数。 t_stu...
  • 今天在做项目的数据库设计时,突然发现自己在的主键设置方面太过片面,对于逻辑主键和联合主键的理解也很少。索性上网百度了一下,看到了一些论坛中的兄弟们的讨论,其中很多的分析让我顿时清醒了很多...
  • 数据库表中对储存数据对象予以唯一完整标识的数据列或属性的组合。一个数据列只能有一个主键,且主键的取值不能缺失,即不能为空值(Null)。 在关系数据库设计中,业务主键是一个由以及真实存在于世界中的属性...
  • 数据库主键

    2019-09-29 02:48:39
    主键有两种选用策略:业务主键和逻辑主键业务主键是使用有业务意义的字段做主键,比如身份证号、银行账号等;逻辑主键是使用没有任何业务意义的字段做主键,完全给程序看的,业务人员不会看的数据。因为很难保证...
  • 数据库主键

    2011-06-07 09:52:14
    数据库设计中我们经常会存在是否为建立逻辑主键(代理主键)的问题。 使用逻辑主键的好处:     1.业务系统中需要关联时使用逻辑ID进行关联--而不是有业务ID做关联--使业务系统具有最大的灵活性,及...
  • 今天在做项目的数据库设计时,突然发现自己在的主键设置方面太过片面,对于逻辑主键和联合主键的理解也很少。索性上网百度了一下,看到了一些论坛中的兄弟们的讨论,其中很多的分析让我顿时清醒了很多。下面开始贴...
  • 数据表主键,外键

    2019-09-22 15:13:15
    1.主键分为:逻辑主键和业务主键 逻辑主键:没有任何的含义,只是为了标识当前列在当前数据库表里的唯一标识; 业务主键:业务主键就是具有真实意义的,就比如身份证,银行卡号,员工编号,一旦变化,难以维护。 ...
  • 主键是非常不幸的符号,因为“初级”的内涵逻辑模型有关的潜意识联想。 因此我避免使用它。 相反,我指的是物理模型的代理键和逻辑模型的自然键。重要的是,每个实体的逻辑模型至少具有一组“业务属性”,其包括...
  • 一、OID,唯一性的标志: Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系。对象的OID和数据库主键对应。为保证OID的唯一性,应该让Hibernate来...表示:采用具有业务逻辑含义的字段作为主键
  • 主键和外键

    2020-10-28 12:30:47
    1.业务主键:有业务意义的字段 2.逻辑主键:完全给程序看的,业余人员不会看的数据 推荐逻辑主键 组合主键: 选择单列作为主键(当通过多列共同唯一标识中的一条记录的时候,此时可以选择多列来工作组成一个主键,
  •  关于数据库表主键设计,一般而言,是根据业务需求情况,以业务逻辑为基础,形成主键。  比如,销售时要记录销售情况,一般需要两个表,一个是销售单的概要描述,记录诸如销售单号、总金额一类的情况,另外一个...
  • 在一个中user_idtype两个字段唯一确定一条记录,那么在设计中是将这两个字段设计为联合主键呢,还是建立一个逻辑主键id,而将这两个字段设计为唯一索引呢?这两种方式有什么区别?哪个更好呢?具体还是要看你的...
  • 1 用自动增长字段作为主键(一般多用int类型定义),也称为非业务主键逻辑主键或者代理主键)意思就是这列数据与业务无关,仅仅作为主键而设计。  优点:自增长字段往往用integer bigint类型,最多占8个字节。...
  • 数据和主键索引是绑定一起的,业务字段更新频繁,一旦修改,索引也要跟着变 使用主键自增的性能会快很多,主键自增就会让数据顺讯添加到中 多关系 在设计数据库的时候,间关系尽量避免出现多对多,当出现多对多的...
  •  Hibernate采用对象标识符,也就是通常我们所说的OID来创建对象和数据库表里记录的对应关系,对象的OID表里的主键对应,所以说OID是非常...所以通常我们设计都会设计主键的值为自动增加,没有业务逻辑含义的一组...
  • 干货:主键是关系表中记录的唯一标识。主键的选取非常重要:主键不要带有业务含义,而应该使用BIGINT自增或者GUID类型。...通过对数据库表创建索引,可以提高查询速度。通过创建唯一索引,可以保证某一列...
  • 中的唯一索引会和逻辑删除字段互斥,导致逻辑删除后的数据要插入的数据出现重复索引时无法插入。 有如下: CREATE TABLE `pata_biz` ( `ID` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'ID主键', `NAME` ...
  • 数据库表的设计

    2015-04-16 15:41:18
    1、所有InnoDB数据都创建一个和业务无关的自增数字型作为主键,对保证性能很有帮助。 2、杜绝使用text/blob,确实需要使用的,尽可能拆分出去成一个独立的 3、时间戳建议使用TIMESTAMP类型存储 4、IPV4地址...
  • 业务逻辑主键引入库,以后业务逻辑的变化,将很可能对底层数据库结构产生连带影响。 复合主键的引入,很大程度上意味着业务逻辑已经侵入到数据存储逻辑之中。 因此,应尽量避免。但实际情况中,我们必须面对...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 239
精华内容 95
关键字:

数据库表逻辑主键和业务主键