简体   繁体   English

MySQL-如何使用列约束声明主键?

[英]MySQL - How do I declare a primary key using a column constraint?

您好,我正在使用MySQL,并且已经在SQL中使用表约束声明了原子主键,这是不好的做法吗?

When you say "column constraint", you mean this? 当您说“列约束”时,您的意思是?

CREATE TABLE `clients` (
  `id` int(11) NOT NULL auto_increment PRIMARY KEY,
  `created` datetime NOT NULL,
  `email` varchar(150) NOT NULL,
  `notes` text NOT NULL
);

There is nothing inherently bad with either of them (it's just a syntactic difference). 它们中的任何一个都没有本质上的坏处(这只是语法上的区别)。

The "in column" syntax above is slightly shorter so you'd want to use it when you don't care for naming your constraint and PK spans only one field. 上面的“列中”语法稍短一些,因此当您不希望命名约束且PK仅跨越一个字段时,您想使用它。

Conversely, if your want to name the primary key or it is composite, you'd use the "table-level" syntax. 相反,如果您想命名主键或它是复合键,则可以使用“表级”语法。

Here is an example of the named PK spanning two columns: 这是跨越两列的命名PK的示例:

CREATE TABLE `clients` (
  ...
  CONSTRAINT `my_primary_key` PRIMARY KEY (`id1`, `id2`)
);

What you have is best practice. 您拥有的是最佳实践。 Having all constraints after the columns. 在列之后具有所有约束。

Easier to read (at least for me): all constraints (and indexes) are grouped together in the table's definition. 更容易阅读(至少对我来说):所有约束(和索引)都在表的定义中分组在一起。

Consistency: a compound primary key cannot be declared as a column constraint, so this way you have all primary key constraints declared at the same place, in all your table definitions. 一致性:复合主键不能声明为列约束,因此,您可以在所有表​​定义中的同一位置声明所有主键约束。

Less error prone: Foreign Key constraints have to be defined this way. 较少出错:必须以这种方式定义外键约束。 If you try to define them as column constraints, they are (silently) ignored in MySQL! 如果您尝试将它们定义为列约束,则在MySQL中(静默)将其忽略!


I'm not sure what "atomic" is supposed to mean in this case, I guess it means that the key is not compound (composite) but only one column. 我不确定在这种情况下“原子”的含义是什么,我想这意味着键不是复合(复合)键,而是仅一列。

They are just both the same, when you do this column constraint : 当您执行此列约束时,它们都是相同的:

create table xx(
    id int primary key,
    txt text not null   
);

When your database admin tool make a script out of it, this is how it looks like: 当您的数据库管理工具使用脚本制作脚本时,其外观如下所示:

CREATE TABLE xx
(
  id integer NOT NULL,
  txt text NOT NULL,
  CONSTRAINT xx_pkey PRIMARY KEY (id )
)

The advantage of making primary key a table constraint , is you can get to name your primary key in a more descriptive manner. 使主键成为表约束的好处是,您可以用更具描述性的方式来命名主键。

And the another advantage of your first approach(table constraint), should you decided to make a composite primary key, it's possible to make that happen: 第一种方法的另一个优点(表约束)是,如果您决定制作一个复合主键,则有可能实现:

create table yy
(
   country_id int not null,
   city_id int not null,
   population int,
   constraint xx_primary_key primary key(country_id, city_id)
);

You cannot do this with column constraint : 您不能使用列约束来执行此操作:

create table yy
(
   country_id int not null primary key,
   city_id int not null primary key,
   population int not null
);

Either way, your friends are not accurate on column constraint , there is no such thing as column constraint (sic) (they might meant column-level primary key), the information of primary-key-ness of column(s) are not saved on column level(even you are using single column primary key) 无论哪种方式,你的朋友是不准确的列约束 ,有没有这样的事情列约束 (原文如此)(它们可能意味着列级的主键),列(S)的主键岬的信息不会被保存在列级别(即使您使用的是单列主键)

It's just a syntactic convenience to put the PRIMARY KEY on column level, but they are not saved there, your RDBMS will still put that information on table-level 将PRIMARY KEY放在列级别只是语法上的方便,但它们没有保存在那儿,您的RDBMS仍会将这些信息放在表级别上

While not exactly an answer to primary key, here's an example of column-level and table-level stuff as handcrafted by developer: 虽然这不能完全解决主键问题,但下面是开发人员手工制作的列级和表级内容示例:

Sql Server: SQL Server:

create table zz
(
id int not null primary key,
lastname varchar(50) not null check(len(lastname) >= 2),
x numeric(18,4) not null,
y numeric(18,4) not null,
constraint ck_balance check(x - y >= 0)
);

You can see on Sql Server admin tool if it keeps your column-level-intended stuff really resides in the column: 您可以在Sql Server管理工具上看到它是否使您打算使用列级的内容确实驻留在该列中:

CREATE TABLE [dbo].[zz](
    [id] [int] NOT NULL,
    [lastname] [varchar](50) NOT NULL,
    [x] [numeric](18, 4) NOT NULL,
    [y] [numeric](18, 4) NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[zz]  WITH CHECK ADD CHECK  ((len([lastname])>=(2)))
GO

ALTER TABLE [dbo].[zz]  WITH CHECK ADD  CONSTRAINT [ck_balance] CHECK  ((([x]-[y])>=(0)))
GO

ALTER TABLE [dbo].[zz] CHECK CONSTRAINT [ck_balance]
GO

Only column-level check constraint (Lastname field) gets a column-level treatment. 仅列级检查约束(姓氏字段)获得列级处理。 Other things like primary key(even it's a single field) and constraint checking if two numbers are balance are on table-level. 表级还包含主键(即使是单个字段)和约束检查两个数字是否相等的其他内容。

I don't see how your database will benefit on placing the column constraint (primary key) on column level, primary key information gets saved on table-level anyhow 我看不出您的数据库在将列约束 (主键)放在列级时会如何受益,无论如何主键信息都保存在表级

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM