精华内容
下载资源
问答
  • 2021-02-01 22:39:35

    主键是非常不幸的符号,因为“初级”的内涵和与逻辑模型有关的潜意识联想。 因此我避免使用它。 相反,我指的是物理模型的代理键和逻辑模型的自然键。

    重要的是,每个实体的逻辑模型至少具有一组“业务属性”,其包括实体的密钥。 Boyce,Codd,Date等在关系模型中将这些称为候选键。 然后,当我们为这些实体构建表时,它们的候选键在这些表中成为自然键。 只有通过那些自然键,用户才能唯一地识别表中的行; 因为代理键应始终对用户隐藏。 这是因为代理键没有商业意义。

    然而,在没有代理键的情况下,我们的表的物理模型在许多情况下效率低下。 回想一下,非聚集索引的非覆盖列只能通过密钥查找(通常)找到聚簇索引(忽略作为堆积实现的表)。 当我们的可用自然密钥很宽时,这(1)扩大了我们的非聚簇叶节点的宽度,增加了存储要求,并且对非聚集索引的搜索和扫描进行了读取访问; (2)减少聚集索引的扇出,增加索引高度和索引大小,再次增加聚簇索引的读取和存储要求; (3)增加了我们的聚簇索引的缓存要求。 从缓存中追逐其他索引和数据。

    这是一个小的代理键,被指定为RDBMS作为“主键”证明是有益的。 当设置为聚类键时,为了用于从非聚集索引和相关表中的外键查找中查找聚簇索引的键,所有这些缺点都消失了。 我们的聚簇索引扇出再次增加以减少聚簇索引的高度和大小,减少聚簇索引的缓存负载,减少通过任何机制访问数据时的读取(无论是索引扫描,索引搜索,非聚簇键查找还是外键查找) 并降低表的聚簇索引和非聚簇索引的存储要求。

    请注意,仅当代理键很小且聚类键时才会发生这些好处。 如果GUID用作聚类键,则情况通常比使用最小可用自然键时更糟。 如果表被组织为堆,则8字节(堆)RowID将用于键查找,这比16字节GU

    更多相关内容
  • 许多时候实现目标功能都会遇到一张表里两外键指向同一个表主键,即为用一个表1关联另一个表2,1里却使用了两相同的外键去关联2的主键,但是指向2的事物是不同的,若不懂,直接看下列例子



    前言

    前言:许多时候实现目标功能都会遇到一张表里两个外键指向同一个表的主键,即为用一个表1关联另一个表2,表1里却使用了两个相同的外键去关联表2的主键,但是指向表2的事物是不同的,若不懂,直接看下列例子。

    官方文档处理这类问题给的事例——文档链接
     




    一、事物例子

    Flask开发中,作者是在处理评论回复遇到的问题,回复评论表,需要被回复的用户id和用户的id,两个id都指向用户表,向用户表查询得到发出评论的用户和被回复的用户。

    class Reply_comment(db.Model):
        # 回复主评论表
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        r_comment = db.Column(db.BLOB, nullable=False)
        r_comment_existence = db.Column(db.Integer, default=1)
        r_comment_time = db.Column(db.DateTime, default=datetime.now)
        comment_id = db.Column(db.Integer, db.ForeignKey('comment.id'))
         #关联同一一个表————用户表,下两行是主要需要我们处理的
        visitor_id = db.Column(db.Integer, db.ForeignKey('visitor.id')) 
        replied_visitor_id = db.Column(db.Integer, db.ForeignKey('visitor.id')) 
    
    class Visitor(db.Model):
        # 用户表,不用太在意,只是被上表作为关联主键id作用
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        username = db.Column(db.String(15), nullable=False)
        email = db.Column(db.String(20), nullable=False)
        rdategtime = db.Column(db.DateTime, default=datetime.now)
        visitor_type = db.Column(db.Integer, default=3)
        icon = db.Column(db.String(100))

     面对两个外键 visitor_id 和 replied_visitor_id 指向同一表外键不做处理是不被允许的,强行运行就会报错,即使设置了普通的相关 relationship() 参照,报错会提示设置 foreign_keys 参数,只要根据报错提示处理即可。



    二、处理方法



    1.设置foreign_keys 参数

    代码如下:

    class Reply_comment(db.Model):
        # 回复主评论表
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        r_comment = db.Column(db.BLOB, nullable=False)
        r_comment_existence = db.Column(db.Integer, default=1)
        r_comment_time = db.Column(db.DateTime, default=datetime.now)
        comment_id = db.Column(db.Integer, db.ForeignKey('comment.id'))
        visitor_id = db.Column(db.Integer, db.ForeignKey('visitor.id'))
        replied_visitor_id = db.Column(db.Integer, db.ForeignKey('visitor.id'))
        # 添加相关外键foreign_keys参数
        visitor = db.relationship('Visitor', backref='reply_comment', foreign_keys=[visitor_id])
        replied_visitor = db.relationship('Visitor', backref='replied_comment', foreign_keys=[replied_visitor_id])

    在评论表里添加了 visitorreplied_visitor 关系参照,用户表不修改,一般建立 relationship() 参照关系是不需要迁移同步,但添加了 foreign_keys 参数是需要在数据库里面进行建立他们之间关系,所以注意建立了 foreign_keys 参数必须把关系迁移同步到数据库


    2.注意!

    注意:建立了 foreign_keys 参数,必须迁移同步到数据库。 

    foreign_keys=[visitor_id]

    设置 foreign_keys 参数使用 [ ] 括号返回的值是一个对象,即使用 reply_comment.visitor  返回值是一个用户对象

    想获得其他类型,查看官方文档即可,给了相应的方法。




    总结

    总结:处理数据库还是令人恶心,人菜错误多,随便改一点错误又的喝一壶!

    面对此类问题:一个表多个外键关联同一个表的主键时,需要添加foreign_keys 参数,并且需要迁移同步其关系。

    追加总结:面对此处理表之间的关系时,一般是建立有名无实的外键关系,换言之就是:两个表之间是有关系,但是我们不在两表之间建立实质的外键关系,而是以我们自己懂的符号代表他们之间的关系。因为外键建立过多会影响数据库的查询速度,降低响应速度,有时还会带来一些其他的bug,因此在建立外键时,因谨慎考虑,尽量少建立或者不建立实质的外键关系。在使用时在后端自己查询再使用,比使用外键去查更快;比如本文的双外键也不应该建立实质的外键关系,而是建立他们之间的虚拟的外键关系,加快速度和避免互锁干死数据库。(21.10.4改)

    参考文章:

    Configuring how Relationship Joins — SQLAlchemy 1.4 Documentation

     SQLAchemy中处理两张表之间存在多个外键的情况_buptter的博客-CSDN博客

    展开全文
  • sql 关于一表多个主键唯一性的约束

    万次阅读 2019-02-27 17:28:15
    1.对于一般的,我们只需设一个主键,防止重复,但是我们如果设置多个主键,是每个主键都唯一性吗?还是多个主键组合起来具有唯一性 2.答案肯定是多个主键合起来具有唯一性,话说太多,现在上例子 3.例如,我建...

    1.对于一般的表,我们只需设一个主键,防止重复,但是我们如果设置多个主键,是每个主键都有唯一性吗?还是多个主键组合起来具有唯一性

    2.答案肯定是多个主键合起来具有唯一性,话说太多,现在上例子

    3.例如,我建了有三个主键的表,如图:

    4.我可以如下图所示添加数据,说明各个主键的唯一性不是单独的,如果是单独的,肯定无法添加了

    5.但是我不可如下图,插入数据:

     

    展开全文
  • 一、确立主键规范每了解数据库设计的人都知道,主键对于一张表来说是一很重要,甚至必需的部分。这确实是事实,主键是好的数据库设计的一部分。主键是数据库确保数据行在整张唯一性的保障。它是定位到一条记录...

    本文的目标就是要确认那些使用了主键,却混淆了主键的本质而造成的一种反模式。

    一、确立主键规范

    每个了解数据库设计的人都知道,主键对于一张表来说是一个很重要,甚至必需的部分。这确实是事实,主键是好的数据库设计的一部分。主键是数据库确保数据行在整张表唯一性的保障。它是定位到一条记录并且确保不会重复存储的逻辑机制。主键也同时可以被外键引用来建立表与表之间的关系。

    难点是选择那一列作为主键。大多数表中的每个属性值都有可能被很多行使用。例如姓名,电子邮件地址等等都不能保证不会重复。

    在这样的表中,需要引入一个对于表的域模型无意义的新列来存储一个伪值。这一列被用作这张表的主键,从而通过它来确定表中的一条记录,即便其他的列允许出现适当的重复项。这种类型的主键列我们通常称其为伪主键或者代理键。

    大多数数据库提供一种和当前处理事务无关的底层方案,来确保每次都能生成全局唯一的一个整数作为伪主键,即使客户端此时正发起并发操作。

    主键存在的作用:

    1、确保一张表中的数据不会出现重复行。

    2、在查询中引用单独的一行记录。

    3、支持外键。

    二、反模式:以不变应万变

    很多的书、文章以及程序框架都会告诉你,每个数据库的表都需要一个主键,且具有如下三个特性:

    (1)、主键的列名都叫做Id;

    (2)、数据类型是32位或者64位的整数

    (3)、主键的值是自动生成来确保唯一的。

    在每张表中都存在一个叫做Id的列是如此地平常,甚至Id已经成为了主键的同义词。很多程序员在一开始学习SQL时就被灌输了错误的概念。认为每张表都要增加一列Id,这显然太过于随意。

    1、冗余键值

    2、允许重复项

    一个组合键包含了多个不同的列,组合键的典型场景就是想上节中乱穿马路中的Contact表。主键需要确保一个给定的Product_Id和Account_Id的组合在整张表中只能出现一次,虽然同一个值可能在很多不同的配对出现。

    然而,当你使用了Id这一列作为主键,约束就不是Account_Id和Product_Id的组合必须唯一了。当你用这张交叉表去查询Account_Id和Product_Id的关系时,重复项会意料之外的结果。要确保没有重复项,你可以在Id之外,额外声明另外两列需要一个UNIQUE约束。但是当你在Account_Id和Product_Id这两列上应用了唯一性约束,Id这一列就会变成了多余的列。它已经背离了主键的初衷了。

    0f57c2eeb9865f4ffabb969af0e44528.png

    3、关键字意义不明确

    Id这个词是如此地普通,完全无法表达更深沉的意思,特别是在你做两张表连接查询,而他们都有一个叫做Id的主键时。

    select *

    from Accout as a

    join Bug b on (b.toId = a.Id)

    这种查询必须在查询时指定列别名,否则其中的一个Id列会覆盖掉另一列的Id的值。

    同时有两张表有相同的Id列的情况下也不能够使用using关键字。

    比如:SQL支持一种简洁的表达式来表示两张表联结(using)。如果两张表有同样的列名,就可以用如下的表达式来重写上面的需求。

    select * from Account join Bug using(Bug_id);  --一个主键,一个外键。

    然而,如果所有的表都要求定义一个叫做id的伪主键,那么将不能使用这种简写方式。

    4、使用组合键

    一些开发人员觉得组合键太难使用,如果要比较两个键值,必须比较其包含的所有列的值;一个引用组合键的外键,其本身也必须是一个组合外键。此外,使用组合键需要打更多的字。其实这是不对的。组合键的适当的时候是应该被使用的。

    三、识别反模式

    1、我觉得这张表不需要主键。

    这么说的人一定是误解了“主键”和“伪主键”的含义,每张表都必须要有一个主键,这个是毫无疑问的。实际上可能这个人需要的是一个组合键,或者一个更自然的列名来做主键。

    2、我怎么能在多对多的表中存储重复的项?

    在一个对多对关系的交叉表中需要声明一个主键约束。或者至少需要有一个针对那些被引用作为外键的唯一约束。

    四、合理使用发模式

    使用伪主键,或者通过自动增长的整型的机制本身没有什么错误,但不是每张表都需要一个伪主键,更没有必要将每个伪主键都定义成Id。

    对于太长而不方便实现的自然键来说,伪主键是一个很好的代替品。比如在一个记录文件系统的所有文件属性的表中,文件路径是一个很好的自然键,但对一个字符串列做索引的开销会很大。

    五、解决方案:裁剪设计

    主键是约束而非数据类型。你可以定义任意列或任意多个的列作为主键。只要其数据类型支持索引。另外在此必须要补充的是,在SqlServer中,主键和聚集索引并没必然的关系。SqlServer只是默认将聚集索引建在主键上,实际上你完全可以将聚集索引手动定义到非主键列。

    1、为主键选择更有意义的名称

    比如为Product这张表的主键应该叫做Product_Id。

    2、外键应该尽可能地和所引用的列使用相同的名称,这通常意味着:一个主键的名称应该在整个数据库的设计中唯一;任意两张表都不应该使用相同的名称来定义主键,除非其中之一引用了另外一个作为外键。然而凡是都有例外,又是外键的名称需要和其所引用的主键区分开,从而使的它们之间的引用关系表现得更加清晰。

    比如在一张外键表中将外键声明为create_by(由谁创建)。

    规则

    自然键

    代理键

    主键必须唯一的识别每一记录

    但与输入和人为错误有关

    系统自生成的数据是唯一的

    一个记录的主键不能为空

    只有数据可知时才能输入记录

    当记录生成时才被系统建立

    当生成记录时,主键的值必须存在

    只有数据可知时才能输入记录

    当记录生成时才被系统建立当记录生成时才被系统建立

    主键必须保持稳定——你不能更改主键的域

    自然键与一些商业规则和其他外部影响有关

    代理键对程序功能和数据保持中立

    主键必须简洁,不要包含过分的属性

    一个自然键可以包含多个域

    代理键只能包含多个域

    主键的值不能改变

    自然键通常改变

    代理键通常不更改

    六、拥抱自然键和组合键

    如果你的表中包含一列能够确保唯一、非空以及能够用来定位一条记录,就别仅仅因为传统而觉得有必要再加上一个伪主键。

    实践证明,一张表中的每一列都在最初的设计之后遭遇改变是很正常的事情。数据库的设计趋向于在整个项目的声明周期中不断地调整和优化,并且决策者也可能一点也不在乎自然键的“神圣不可侵犯”。有时候一个列最开始是像是个很好的自然主键,但随后有允许合法的重复项。此时伪主键便成了唯一的选择。

    在合适的时候也可以使用联合主键,比如一条记录可以通过多个列的组合完全定位。就像上面提到的Contact表,那就通过那些列创建一个联合主键吧。

    总结:我个人的见解就是能用代理键就尽量用代理键。除非代理键真的非常多余,就好似上面的组合键代替复合键的例子一样。

    展开全文
  • 最近学习一点数据库的基本知识,被一个问题困惑了许久:主键是唯一的索引,那么为何一个可以创建多个主键呢? 其实“主键是唯一的索引”这话有点歧义的。举个例子,我们在中创建了一个ID字段,自动增长,并设为...
  • 数据库技术可以有效帮助一组织或者企业科学、有效的管理数据,也是现在很企业招聘数据分析师的必备要求之一。大家如果看过MySQL的书,也可以看我的知识导图做一复习,因为是自己的读书笔记,所以的地方也...
  • 数据库主键、唯一约束和索引

    千次阅读 2021-11-23 17:31:46
    (1)一个可以没有主键,而且最多只能个主键。 (2)主键值必须唯一标识中的每一行,且不能为 NULL,即同一个中不可能存在两行数据相同的主键值。 2、MySQL 的 唯一约束。  MySQL唯一约束...
  • 大量数据,批量插入到数据中时,很容易造成主键冲突,重复数据唯一约束插入不进去中,报错的问题出现。 排查错误,去找某条数据,在大量的数据,大量的批处理或者单条执行的sql语句中找数据也是不现实的。 ...
  • 其实我们之前所讲的回,就是两索引树同时使用,先在二级索引树中搜索到对应的主键值,然后在再去主键索引树中查询完整的记录。 但是我今天的问题是,两不同的二级索引树,会同时生效吗?理论上来说,应该是...
  • 之前松哥在前面的文章中介绍 MySQL 的索引时,小伙伴表示被概念搞晕了,主键索引、非主键索引、聚簇索引、非聚簇索引、二级索引、辅助索引等等,今天咱们就来捋一捋这些概念。 1. 按照功能划分 按照功能来划分,...
  • 索引使用简介一、 关于索引的知识要写出运行效率高的sql,需要对索引的机制...对于dml操作比较频繁的,索引的个数不宜太。2、 什么样的列需要建索引?经常用于查询、排序和分组的列(即经常在where、order或grou...
  • MySQL数据库的主键和外键详解主键主键的定义主键中经常列或列的组合,其值能唯一地标识中的每一行。这样的一列或列称为主键,通过它可强制的实体完整性。当创建或更改时可通过定义 PRIMARY ...
  • 数据库-主键和外键及其约束

    千次阅读 2021-01-16 23:24:36
    1:什么是主键一张表中,用来唯一标识一条记录的字段集,叫做主关键字或者主关键码,简称主键(或主码),这里说"字段集"是因为主键可能用一个字段或者多个字段来表示。举例来看:学生(学号, 姓名, 性别,专业...
  • MySQL联合主键解释

    2020-07-10 21:42:42
    最近学习一点数据库的基本知识,被一个问题困惑了许久:主键是唯一的索引,那么为何一个可以创建多个主键呢? 其实“主键是唯一的索引”这话有点歧义的。举个例子,我们在中创建了一个ID字段,自动增长,并设为...
  • 展开全部首先32313133353236313431303231363533e4b893e5b19e31333366303839,在SQL中(以SQL Server为例),查询存在一个表而不在另一个表中的数据记录的方法,介绍其中4种:1、方法一(仅适用单个字段):使用 ...
  • mysql数据库外键、主键详解

    千次阅读 2021-01-18 18:41:25
    一、什么是主键、外键:关系型数据库中的一条记录中若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键比如学生(学号,姓名,性别,班级)其中每个学生的学号是唯一的,...
  • MySQL数据库的主键和外键详解

    千次阅读 2020-03-20 20:15:42
    主键中经常列或列的组合,其值能唯一地标识中的每一行。这样的一列或列称为主键,通过它可强制的实体完整性。当创建或更改时可通过定义 PRIMARY KEY 约束来创建主键。一个表只能 ...
  • sql多表查询及多表连接查询

    千次阅读 2021-11-11 10:44:05
    多表关系一对一、一对对一、 1.一对一的关系 一对一的关系实现 可以在任意一方添加外键 指向另一方的主键 并且让外键唯一 2.一对(对一) 实现关系 :一对 的一方建立外键,通过外键进行...
  • 关于数据库主键和外键(终于弄懂啦)

    万次阅读 多人点赞 2019-06-18 15:59:59
    转 关于数据库主键和外键(终于弄懂啦) 2018年07月16日 19:44:24 f45056231p 阅读数 19385 ...
  • 在现实的数据库应用中,数据保存在多个相关联的中。基本上没有数据只存在一个中的情况。小的应用系统一般也十几个,大型系统一般上千个。    我们以学生成绩查询为例来讲解的关联。除了Student...
  • 小伙伴们在面试的时候,特别常见的问题,那就是数据库的回。什么是回?为什么需要回? 今天松哥就来和大家聊一聊这话题。 1. 索引结构 要搞明白这问题,需要大家首先明白 MySQL 中索引存储的数据...
  • 关系型数据库中的一条记录中若干个属性,若其中某一个属性组(注意是组)能唯一标识一条记录,该属性组就可以成为一个主键。 比如:   学生(学号,姓名,性别,班级)   其中每个学生的学号是唯一的,学号...
  • MySQL添加主键和外键

    千次阅读 2021-02-02 09:02:41
    MySQL DBMS,MySQL的概念,数据库分类,以前MySQL的部署中的一些概念 #DBMS:数据库管理系统,用于管理数据库的大型软件.mysql就是dbms的一种 #Mysql:是用于管理文件的一软件 #服务端软件 #socket服务端 #本地文件操作 ...
  • 1、声明主键的方法:您可以在创建的时候就为加上主键,如:CREATE TABLE tbl_name ([字段描述省略...], PRIMARY KEY(index_col_name));.../*创建一qq,将qq_id设为主键,且没有对其进行NOT...
  • 展开全部insert一般是用来给插入一条62616964757a686964616fe58685e5aeb931333433636666指定的列值的,但是,insert还存在另一种形式,可以利用它将一条...假如你从另一张表中合并客户列表到你的Custumers,...
  • 概述 这是 Alexey Milovidov(ClickHouse 的创建者)给出的关于复合主键的答案的...主键可以多少列?存储驱动器上的数据布局是什么?任何理论/实践限制吗? 某些行缺少数据的列可以成为主键的一部分吗? This is...
  • 数据库的主键表和外键

    千次阅读 2013-03-24 11:06:33
    想写这是因为自己刚好在尝试建一数据库,而数据库的各个之间的关系不是很清楚,没有形成一整体的关系,所以就尝试着将数据库形成一整理的关系,我 敢说很跟我一样的同学原来做课程设计,肯定就是随便...
  • 学术定义:解决数据的一致性与正确性主键约束设置主键格式 PRIMARY KEY [默认值]每个只有一个主键,但可以复合主键,所谓复合主键就是列组合的主键例子:在test_db数据库中创建tb_emp3数据,其主键为id,格式...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,161
精华内容 16,064
关键字:

一张表有多个主键例子