我有一个非常简单的数据库,其中有2个表。这是我的表的一个示例:
我已将代码列ID设置为主键... 并且访问代码栏id_fk是外键。
每当我通过phpmyadmin将数据添加到代码表时,access_codes列id_fk都不会为我提供与主键相同的数据。
我已经在phpmyadmin中建立了被索引的id_fk的关系,并在代码表中建立了PK的外键。
我将运行一条SQL语句:git pull-autostash
代码INSERT INTO
令牌(
但是,当我查看access_codes表时,数据未与Codes表关联。
我在做什么错?
答案 0 :(得分:1)
您误解了外键是什么。它们不是向多个表添加数据的神奇方法。他们是约束。它们限制了access_codes.id_fk
列中可能出现的值。在这种情况下,唯一允许的值是出现在codes.id
列中的值。但是,每次在access_codes
中插入新行时,都不会在codes
中插入新行。您必须自己做。
附带说明-在这种情况下,将所有数据保存在一个表中会更简单吗?
已添加:数据库密钥崩溃课程
让我们从主键开始,这很有帮助。如今,大多数RDBMS都将表视为大行。这些行是无序的(每次您从select * from mytable
执行时,您可能会以不同的顺序返回它们),没有任何区别。就像您将100个绿色的球扔到一个桶中一样,您将无法分辨哪个是哪个球。如果您想对它们进行区分,则需要给每个球打一个独特的标记,例如在每个球或某物上写一个不同的数字。
在使用数据库时,我们通常希望区分行。每当我们对表执行操作时,通常都希望更新或删除表中的特定行,因此我们需要该唯一的标识标记。数据库引擎制造商认识到这一点,并且当今大多数RDBMS提供两个重要功能-主键和auto_increment列(尽管这些功能的名称可能因数据库而异)。
将某列标记为“主键”列时,这意味着该列将包含每一行的唯一ID。数据库引擎不允许,因为您在主键列中插入两行具有相同值的行(或进行更新以使其成为行),因为该列的目的是唯一地标识每一行。具有相同ID的两行将无法达到此目的。
请注意,您还可以将多列用作主键。在这种情况下,每一列中的值不必唯一,但是表中所有行中每一行中值的组合必须唯一。
此外,如果需要,您可以具有其他“唯一”列-甚至还有一个“唯一索引”,这再次使数据库拒绝插入具有非唯一值的行。
但是主键是特殊的。首先,因为它告诉看表的任何人“这是区分这些行的官方方式”,其次,因为大多数RDBMS实际上以与主键相同的顺序将行存储在磁盘上。这意味着如果您知道行的主键值,则查找行非常快。
因此,大多数人只使用主键来标识行,并且很少发现其他唯一索引(尽管它们有时会发生)。
Auto_increment是一项有助于生成这些唯一ID的功能。如果将一列(通常是整数/数字)标记为“ auto_increment”(某些RDBMS仅允许在每个表中标记一列),则在插入新行时,该列将自动获得比以前的最大值大1的值。在那张桌子上。唯一标识符变得容易。
现在介绍外键。
由于某些原因,我们需要将两行(通常在不同的表中,但有时在同一表中)链接在一起,这很常见。
例如-我们公司生产与停车付款有关的软件。因此,我们有一个表格,列出了所有当前停放在某处的汽车。每行代表一辆停放的汽车。它包含车牌号,当停车开始时,yadda yadda。然后,我们还有另一个表格列出了所有客户-用户名,密码哈希,电话号码,电子邮件,作品。每行代表一个客户。另一个表格列出了我们运营的所有停车场。每个停车场一排。名称,地址,GPS坐标,描述,价格等。
每个表都有一个auto_increment ID
列,它也是主键。
现在,在第一个表格中-列出了哪些车停放了-对于每辆车,我们还想知道哪个客户将其停在哪个停车场。因此,我们有两列-client_id
和lot_id
。在client_id
列中,存储客户表的ID
的值,在lot_id
中,存储手数表的值。
例如,如果我们看到车牌为AB1234
的汽车已停放,并且属于ID为222
的客户,那么我们可以转到客户表,找到该行ID为222
的人,那就是约翰·史密斯。同样,我们可以查找特定批次,因为我们知道其ID值。
这就是外键的全部-仅仅是将一行的唯一ID放入另一行的想法,这样您就可以知道哪一行与哪一行有关(同样,“关系”部分就在哪里)来自“关系数据库”中。)
现在,这还需要介绍一件事-外键约束-这是RDBMS制造商的一项了不起的功能。并非严格要求您使用它,但我建议您使用它。就是那样。
基本上,它的作用是可以告诉RDBMS:“此表中的此列实际上是该表中该列的外键”。然后数据库将帮助您确保一切都准备就绪。
例如,如果在客户表中没有ID为222
的客户,我将无法为客户222
插入停放的车辆。而且,如果我尝试删除客户端222
,它将不允许我这样做,因为仍然有停车场停放它。换句话说,它可以确保,无论我从停放的车辆表中选择的哪一行,如果我随后从该行中获取客户ID,则客户表中总会有一行与此ID匹配。在地狱中,我无法绕开它。这样可以避免很多麻烦。