如何避免主键错误

zte4gxcn  于 2021-06-20  发布在  Mysql
关注(0)|答案(5)|浏览(321)

嗨,我是一个数据库的初学者,因此我想问你我应该使用哪些属性作为主键来避免错误:

CREATE TABLE customer(
    name
    first_lastname
    street
    ZIP_code
    mobile_phone
    telephone
    email
    gender
    birthdate
    nationality);

或者我想添加idcustomer作为auto\ u increment,但我不确定这是否是个好主意。

qv7cva1a

qv7cva1a1#

我想添加idcustomer作为auto\ u increment,但我不确定这是否是个好主意。
这的确是个好主意。
其他列(属性)不一定具有唯一值。换句话说,它们不适合用作自然主键。什么样的值可以用作自然主键?可能是员工号码。产品序列号可能有用。纳税人身份证号码(社会保险号码)不起作用:错误使用重复号码的人数惊人。选择一个真实世界的项作为主键的唯一性标准是如此之高,以至于大多数数据库设计者甚至不去尝试。
因此,创建一个有保证的唯一主键通常是一个好的设计。这种密钥的行话是代理主键。大多数dbms系统(包括mysql)都为此提供了自动递增的数字。
你可以从两个约定中选择一个来命名它 id 价值观。一是称之为 id . 另一种是称之为 customer_id (表名带有 _id 添加)。当您开始在其他表中使用这些值来建立关系时,第二种方法将帮助您保持事情的正确性。
例如,您可能有一个sales表。该表可能有以下列:

sales_id      autoincrementing pk
customer_id   the id of the customer to whom the sale was made. (foreign key)
item_sold     description of the item
list_price
discount
net_price

你明白了。阅读主键和外键。在“逻辑数据库设计”的行话中,您可以了解实体(客户、销售)和关系。每个表都有自己的一系列自动递增值。
然后,您可以使用这样的查询来查找每个客户的销售额。

SELECT customer.name, customer.first_lastname,
        COUNT(sales.sales_id) number_of_sales,
        SUM(sales.net_price) revenue
   FROM customer
   JOIN sales ON customer.customer_id = sales.customer_id
  GROUP BY customer.customer_id, customer.name, customer.first_lastname

在这里 sales 实体与 customer 实体。这是通过 customer_id 每个属性中的属性 sales 指向客户的行。
将id作为每个表的第一列也是一种约定。
约定是好的:它们可以帮助下一个人查看您的应用程序。它们也帮助你未来的自我。
注意:我的sales表只是一个示例,说明自动递增id值可能有多大用处。我并不认为这是一个很好的布局为现实世界的销售表:它不是。

pobjuy32

pobjuy322#

最安全的方法是创建一个名为 id 在每张table上。别做英雄了,去找个没签名的小人物吧。pk溢出,无论多么不可能,都不是您想要的问题。
您可以使用: id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY 或者用 SERIAL 关键字,它是的别名 BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE 请记住,如果使用基于语句的复制,自动增量可能会导致问题。在5.7.6之前,基于语句的复制是默认的。
使用合成键将要建模的对象的特征与该对象的唯一标识符分离,如果需要更改模式,这非常方便。修改mysql pk很昂贵。它还保证您将有一个唯一的、非空的列用于外键引用。另外,一些orm期望 id pk列-如果你是那种人。
使用mysql可以创建一个复合聚集索引,它是一个具有多个列的主键。如果您确定表永远不会变得庞大,并且您将使用复杂的过滤器定期访问表,这些过滤器指定该键中最左侧的列子集,那么这可能是一种优化。不过,我不会用这种方法。
不过,innodb表需要一个主键。即使没有显式地创建一个列,数据库也会隐式地选择它找到的第一个唯一列。如果没有,它将创建一个名为gen\u clust\u index的隐藏列。

pjngdqdw

pjngdqdw3#

主键有几个理想的属性(其中一些非常明显,但我们将一一列举)
non-null-(保证每行的所有pk列都有一个非null值)
unique-(没有两行具有相同的值集。曾经)
简单-(单列,本机数据类型)
short-(集群键将在每个辅助索引和外键中重复)
不可变-(赋值后,值不会更改)
匿名-(不携带任何有意义的信息)
我们可以就这些属性中的每一个、含义和好处以及不具有这些属性的主键的缺点持有意见并进行讨论。但很多人最终都会对什么最重要,什么根本不重要发表意见。)
我有理由持有每一个和每一个这些财产是可取的。我认识到其他人并不持有同样的观点。
如果此列表有效,则代理主键可以满足所有这些条件。
在mysql中,实现代理主键的一种可能方法是在表中添加一个额外的列:

CREATE TABLE mytable 
 ( id                INT NOT NULL AUTO_INCREMENT PRIMARY KEY  COMMENT 'PK'
 , cust_email        VARCHAR(255) NOT NULL                    COMMENT 'UX1'
 , cust_name_title
 , cust_name_first
 , cust_name_last
 , cust_name_suffix
 , cust_addr_street
 , cust_addr_line2
 , cust_addr_city
 , cust_addr_state
 , cust_addr_postal_code
 , UNIQUE KEY customer_UX1 (cust_email) 
 )

请注意,使用自动增量不是一个要求。这是一个许多人认为有用且易于使用的特性(有一些关于自动增量的细节使得它在主键方面不是一个完美的特性。)
重要的
我并没有Assert使用代理主键是正确的方法,或者说是唯一的方法。
成功的数据库实现项目不需要代理主键。许多成功的项目都是使用自然密钥实现的。
但我会注意到(最后)一些坚信自然键的人已经被严重烧伤了,因为事实证明(在项目的稍后阶段,新发现的需求)所选择的自然键并不能满足我列出的一个(或多个)“理想属性”。

wyyhbhjk

wyyhbhjk4#

主键是唯一标识表中行的一列或一组列。记住这一点,您可以创建任何列来标识 customer 行作为主键唯一。您可以使用电话号码或名字、姓氏和电话号码的组合作为主键。但更普遍的方法是添加一个额外的列,可能名为 idcustomer 就像你想的或者 customer_id 或者只是 id ,这对于每个客户都是唯一的,并使其成为主键;使此整数列 auto_increment 是个好主意。

gwo2fgha

gwo2fgha5#

令人惊讶的是,到目前为止,没有一个答案询问您的业务需求。您是否了解您的业务流程、与客户发生的交互以及如何在业务领域识别客户?标识属性(例如,在电子商务应用程序中可能是登录名)通常应该是表中的键。仅仅添加一个自动增量是不正确的,除非你明白这个键是用来做什么的。

相关问题