您好,我正在使用 MySQL,并且已经在我的 SQL 中使用表约束声明了原子主键,这是一个不好的做法吗?
4 回答
当您说“列约束”时,您是说这个吗?
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`)
);
你所拥有的是最佳实践。在列之后具有所有约束。
更容易阅读(至少对我而言):所有约束(和索引)都在表的定义中组合在一起。
一致性:不能将复合主键声明为列约束,因此通过这种方式,您可以在所有表定义中的同一位置声明所有主键约束。
不易出错:必须以这种方式定义外键约束。如果您尝试将它们定义为列约束,它们会在 MySQL 中(默默地)被忽略!
我不确定在这种情况下“原子”应该是什么意思,我想这意味着密钥不是复合(复合),而只有一列。
虽然不完全是主键的答案,但这里有一个由开发人员手工制作的列级和表级内容的示例:
Sql 服务器:
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
只有列级检查约束(姓氏字段)获得列级处理。其他诸如主键(即使它是单个字段)和约束检查两个数字是否平衡的事情都在表级别。
我看不到您的数据库将如何将列约束(主键)放在列级别上,主键信息无论如何都会保存在表级别上
当您执行此列约束时,它们都是相同的:
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 放在列级别只是一种语法方便,但它们没有保存在那里,您的 RDBMS 仍会将这些信息放在表级别