您好我正在使用MySQL并且已经在我的SQL中使用表约束声明了原子主键,这是一种不好的做法吗?
答案 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
只有列级检查约束(姓氏字段)才能获得列级处理。其他一些东西,如主键(即使它是单个字段)和约束检查,如果两个数字是平衡的是在表级别。
我没有看到您的数据库如何在列级别放置列约束(主键)时受益,主键信息无论如何都会保存在表级别