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

时间:2012-05-05 15:09:45

标签: mysql sql database database-design

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

4 个答案:

答案 0 :(得分:2)

当你说“列约束”时,你的意思是这个吗?

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
);

其中任何一个都没有任何本质上的坏处(这只是语法差异)。

上面的“in column”语法略短,所以当你不关心命名约束时,你想要使用它,而PK只跨越一个字段。

相反,如果您想要命名主键或它是复合键,则使用“表级”语法。

这是一个名为PK的示例,跨越两列:

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

答案 1 :(得分:1)

你拥有的是最佳实践。列之后有所有约束。

易于阅读(至少对我来说):所有约束(和索引)都在表的定义中组合在一起。

一致性:复合主键不能声明为列约束,因此这样就可以在所有表​​定义中的同一位置声明所有主键约束。

不易出错:必须以这种方式定义外键约束。如果您尝试将它们定义为列约束,则在MySQL中(静默地)忽略它们!


在这种情况下,我不确定“原子”是什么意思,我想这意味着键不是复合(复合)而只是一列。

答案 2 :(得分:0)

当你执行列约束时,它们都是相同的:

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

当您的数据库管理工具从中创建脚本时,它的外观如下:

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

将主键设为表约束的优点是,您可以以更具描述性的方式命名主键。

你的第一种方法(表约束)的另一个优点是,如果你决定制作一个复合主键,它可能会发生这种情况:

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)
);

您不能使用列约束

执行此操作
create table yy
(
   country_id int not null primary key,
   city_id int not null primary key,
   population int not null
);

无论哪种方式,你的朋友对列约束都不准确,没有列约束(原文如此)(它们可能意味着列级主键) ,列的 primary-key-ness 的信息不会保存在列级别上(即使您使用的是单列主键)

将PRIMARY KEY置于列级别只是一种语法上的方便,但它们不会保存在那里,你的RDBMS仍会将这些信息放在表级

答案 3 :(得分:0)

虽然不完全是主键的答案,但这里是由开发人员手工制作的列级和表级内容的示例:

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)
);

你可以在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

只有列级检查约束(姓氏字段)才能获得列级处理。其他一些东西,如主键(即使它是单个字段)和约束检查,如果两个数字是平衡的是在表级别。

我没有看到您的数据库如何在列级别放置列约束(主键)时受益,主键信息无论如何都会保存在表级别