SQL中添加唯一约束

本文介绍如何在数据库中创建、修改和删除唯一约束,确保特定列值的唯一性,适用于非主键列及允许空值的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、创建唯一约束
  创建唯一约束来确保不参与主键的特定列的值不重复。尽管唯一约束和主键都强制唯

一性,但在下列情况下,应该为表附加唯一约束以取代主键约束:
  
  如果要对列或列的组合强制唯一性。可以为表附加多个唯一约束,而只能为表附加一

个主键约束。
  
  
  如果要对允许空值的列强制唯一性。可以为允许空值的列附加唯一约束,而只能将主

键约束附加到不允许空值的列。当将唯一约束附加到允许空值的列时,确保在约束列中最

多有一行含有空值。
  创建唯一约束
  
  I、在数据库关系图中右击将包含约束的表,然后从快捷菜单中选择"属性"命令。
  -或-
  
  为将包含约束的表打开表设计器,在表设计器中右击,然后从快捷菜单中选择"属性"

命令。
  
  II、选择"索引/键"选项卡。
  
  
  III、选择"新建"命令。系统分配的名称出现在"索引名"框中。
  
  
  IV、在"列名"下展开列的列表,选择要将约束附加到的列。若要将约束附加到多个列

,在后续行中选择其它的列。
  
  
  V、选择"创建 UNIQUE"复选框。
  
  
  VI、选择"约束"选项。
  当保存表或关系图时,唯一约束即创建在数据库中。
  
  如果使用的是 SQL Server,可以控制键值的排序次序以及当存在重复键时所采取的操

作。为此,应创建唯一索引取代唯一约束。
  
  2、修改唯一约束
  
  当要更改约束附加到的列、更改约束名称或设置附加属性时,修改唯一约束。
  
  修改唯一约束
  
  I、在数据库关系图中右击包含约束的表,然后从快捷菜单中选择"属性"命令。
  -或-
  
  为包含约束的表打开表设计器,在表设计器中右击,然后从快捷菜单中选择"属性"命

令。
  
  II、选择"索引/键"选项卡。
  
  III、从"选定的索引"列表中选择要更改的约束。
  
  IV、完成下表中的操作:
   

  当保存表或关系图时,约束即在数据库内被更新。
  
  3、删除唯一约束
  当要删除对包含在约束表达式中的列或列组合中输入值的唯一性要求时,删除唯一约

束。
  
  删除唯一约束
  I、在数据库关系图中,右击包含约束列的表,然后从快捷菜单中选择"索引/键"命令


  -或-
  
  为包含约束的表打开表设计器,在表设计器中右击,然后从快捷菜单中选择"索引/键"

命令。
  II、从"选定的索引"列表中选择唯一约束。
  III、选择"删除"按钮。
  注意 选择"删除"按钮将导致一个无法撤消的操作,而且不保存对数据库关系图所做

的所有其它更改。若要撤消该操作,不保存更改即关闭当前的数据库关系图或表设计器窗

口以及所有其它打开的数据库关系图和表设计器窗口。
  
  
  当保存表或关系图时,约束即从数据库中被删除。

<think>我们正在讨论如何添加唯一性约束和唯一索引。根据引用[1],唯一索引和唯一约束在功能上类似,但存在一些区别。引用[2]提到在启用唯一或主键约束时可以指定using_index_clause。 用户的问题:如何用SQL语句添加唯一索引和唯一约束?特别是使用ALTER TABLE ADD CONSTRAINT。 首先,我们需要明确: 1. 唯一约束可以通过ALTER TABLE ADD CONSTRAINT来添加,它会自动创建一个唯一索引来支持约束。 2. 唯一索引则是通过CREATE UNIQUE INDEX语句直接创建。 在SQL Server中,唯一约束和唯一索引的主要区别在于: - 唯一约束是一种逻辑约束,用于确保列的唯一性,它会在后台自动创建一个唯一索引。 - 唯一索引是一种物理结构,除了保证唯一性外,还可以用于优化查询性能。 - 唯一约束不允许包含可空列(除非是筛选索引,但SQL Server唯一约束要求唯一键列必须是非空的?实际上,SQL Server允许唯一约束的列中有多个NULL值,因为NULL示未知,所以多个NULL不违反唯一约束?但注意,在唯一约束中,只允许一个NULL值?这取决于ANSI_NULLS的设置?实际上,在SQL Server中,唯一索引允许有一个NULL值(如果列可为空),但唯一约束也是通过唯一索引实现的,所以行为相同?) 但根据引用[1],唯一约束和唯一索引在行为上非常相似,但唯一约束更明确地达了业务规则。 添加唯一约束的语法: ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE (column1, column2, ...); 添加唯一索引的语法: CREATE UNIQUE INDEX index_name ON table_name (column1, column2, ...); 另外,引用[2]提到在启用约束时可以使用using_index_clause,但这是Oracle的语法,在SQL Server中并不适用。因此,在SQL Server中,我们只能通过上述两种方式。 所以,针对用户的问题,我们分别给出两种操作的SQL语句。 注意:在SQL Server中,当添加唯一约束时,系统会自动创建一个唯一索引。这个索引的名如果不指定,系统会生成一个随机的名。我们可以通过指定索引选项(如填充因子)来创建唯一索引,然后将其用于约束吗?在SQL Server中,我们可以在创建约束时指定索引选项,但语法与Oracle不同。 在SQL Server中,我们无法在ALTER TABLE ADD CONSTRAINT语句中直接指定索引的存储参数(如填充因子)。但是,我们可以先创建一个唯一索引(带有指定的选项),然后通过约束使用这个索引吗?实际上,在SQL Server中,唯一约束必须使用一个唯一索引,但创建约束时不能直接关联一个已存在的索引(除非在创建约束时使用WITH INDEX选项?但SQL Server不支持这种语法)。 因此,在SQL Server中,通常的做法是: - 如果要创建唯一约束,使用ALTER TABLE ADD CONSTRAINT。 - 如果要控制索引的存储选项,可以先创建唯一索引,然后再创建约束(但SQL Server不允许将约束绑定到现有索引?)——实际上,在SQL Server中,唯一约束会自动创建索引,我们无法在创建约束时使用一个已经存在的索引。所以,如果需要对索引进行详细设置,应该直接创建唯一索引,这样在功能上等同于唯一约束(除了约束在sys.objects中有记录,而索引在sys.indexes中)。 但是,从SQL Server 2005开始,我们可以通过先创建唯一索引(非聚集),然后使用该索引来支持约束吗?实际上,SQL Server不支持在创建约束时使用一个已存在的索引(除了主键约束可以使用聚集索引,但唯一约束不行?)。所以,通常我们只能选择其中一种方式。 总结: 1. 添加唯一约束(系统自动生成唯一索引): ```sql ALTER TABLE 名 ADD CONSTRAINT 约束名 UNIQUE (列1, 列2, ...); ``` 2. 添加唯一索引(直接创建索引): ```sql CREATE UNIQUE [CLUSTERED | NONCLUSTERED] INDEX 索引名 ON 名 (列1, 列2, ...) WITH (FILLFACTOR = 70, ...); -- 可以指定索引选项 ``` 3. 唯一约束和唯一索引的选择: - 如果业务逻辑要求强制唯一性(作为数据完整性约束),则使用唯一约束。 - 如果主要是为了查询性能,同时要求唯一性,则使用唯一索引。 - 唯一约束可以用于外键引用,而唯一索引不能直接用于外键(但外键可以引用唯一索引的列)。 实际上,在SQL Server中,外键可以引用唯一索引(不一定要求是唯一约束)。所以,唯一索引也可以支持外键。 因此,我们给出两种方法的示例。 示例1:在Employee的Email列上添加唯一约束 ```sql ALTER TABLE Employee ADD CONSTRAINT UQ_Employee_Email UNIQUE (Email); ``` 示例2:在Employee的Email列上添加唯一索引(并指定填充因子) ```sql CREATE UNIQUE INDEX IXU_Employee_Email ON Employee (Email) WITH (FILLFACTOR = 80); ``` 注意:唯一约束和唯一索引在确保唯一性方面是等效的,但约束更符合业务规则的达,而索引则更侧重于性能优化。 另外,如果需要在多列上创建复合唯一约束/索引,只需在括号内列出多个列,用逗号分隔。 最后,关于允许NULL值的问题:在SQL Server中,唯一索引允许有一个NULL值(因为NULL被视为未知,所以多个NULL值不会被视为重复?)实际上,SQL Server的唯一索引允许列中有多个NULL值,因为唯一索引只检查非NULL值是否唯一。但是,如果索引是复合索引,那么只要非NULL值的组合是唯一的,就可以有多个NULL值。但是,如果希望不允许NULL值,则需要在列上设置NOT NULL约束。 所以,在创建唯一约束或唯一索引时,如果列允许NULL,则只能有一个NULL值(因为唯一约束/索引认为所有NULL值都是相等的?)实际上,在SQL Server中,唯一约束/索引对NULL值的处理是:只允许一个NULL值(如果列可为空),因为唯一约束/索引要求每个值都是唯一的,而NULL被视为一个特殊值,多个NULL值会违反唯一性。但事实并非如此:在SQL Server中,唯一索引允许有多个NULL值。这是因为在唯一索引中,NULL值不被视为彼此相等(根据ANSI SQL标准)。所以,唯一索引不会阻止多个NULL值。但是,如果希望禁止NULL值,必须使用NOT NULL约束。 验证:在SQL Server中,唯一索引允许列中有多个NULL值。例如,在一个允许NULL的列上创建唯一索引,然后插入两行NULL值,不会报错?实际上,在SQL Server中,唯一索引允许有多个NULL值,因为NULL值被认为是未知的,所以两个NULL值不相等。因此,唯一索引不会阻止多个NULL值。但是,如果希望只允许一个NULL值,可以创建一个筛选唯一索引(SQL Server 2008及以上版本),例如: ```sql CREATE UNIQUE INDEX IXU_Employee_Email ON Employee (Email) WHERE Email IS NOT NULL; ``` 这样,只有非NULL值需要唯一,而NULL值可以有多个。 因此,在创建唯一约束时,如果列允许NULL,则可以有多个NULL值吗?实际上,唯一约束SQL Server中也是通过唯一索引实现的,所以行为相同:允许有多个NULL值(因为唯一约束并不认为多个NULL值违反唯一性)。但是,根据ANSI SQL标准,唯一约束应该允许多个NULL值,因为NULL不等于任何值,包括NULL。 所以,结论是:在SQL Server中,唯一约束和唯一索引都允许列中有多个NULL值。 但是,如果希望列中不允许NULL值,则需要在列上添加NOT NULL约束。 下面我们给出完整的SQL语句示例。 注意:在创建唯一约束或索引时,如果中已有数据,需要确保现有数据满足唯一性条件(包括NULL值的情况),否则创建会失败。 最后,生成相关问题。</think>### SQL 添加唯一约束与唯一索引的语句详解 #### 1. **添加唯一约束** 使用 `ALTER TABLE ADD CONSTRAINT` 语法创建唯一约束,系统会自动生成唯一索引支持约束: ```sql -- 单列唯一约束 ALTER TABLE 名 ADD CONSTRAINT 约束名 UNIQUE (列名); -- 多列组合唯一约束 ALTER TABLE 名 ADD CONSTRAINT 约束名 UNIQUE (列1, 列2); ``` **示例**: ```sql ALTER TABLE Employees ADD CONSTRAINT UQ_Employee_Email UNIQUE (Email); -- 邮箱唯一 ALTER TABLE Orders ADD CONSTRAINT UQ_Order_Composite UNIQUE (CustomerID, ProductID); -- 客户+商品组合唯一 ``` #### 2. **添加唯一索引** 直接创建唯一索引(可指定存储参数): ```sql CREATE UNIQUE [CLUSTERED|NONCLUSTERED] INDEX 索引名 ON 名 (列名 [ASC|DESC]) WITH (FILLFACTOR = 值, DATA_COMPRESSION = PAGE); -- 可选参数 ``` **示例**: ```sql CREATE UNIQUE NONCLUSTERED INDEX IX_Product_Code ON Products (ProductCode) WITH (FILLFACTOR = 80); -- 填充因子80% ``` #### 3. **唯一约束 vs 唯一索引的区别** | 特性 | 唯一约束 | 唯一索引 | |--------------------|-----------------------------|-----------------------------| | **创建方式** | `ALTER TABLE ADD CONSTRAINT` | `CREATE UNIQUE INDEX` | | **本质** | 数据完整性规则 | 物理存储结构 | | **NULL值处理** | 允许单个NULL(默认行为) | 允许单个NULL(默认行为) | | **外键引用** | 可作为外键引用目标 | 不可直接作为外键引用目标 | | **索引控制** | 系统自动创建索引 | 显式控制索引类型和参数 | | **删除影响** | 删除约束同时删除关联索引 | 独立删除不影响约束 | > ⚠️ **注意**:在 SQL Server 中,创建唯一约束时会**自动生成唯一索引**,但删除约束不会自动删除索引(需手动操作)[^1]。 #### 4. **高级用法** **包含性索引**(非键列加入索引): ```sql CREATE UNIQUE INDEX IX_Order_Composite ON Orders (OrderID) INCLUDE (CustomerName, OrderDate); -- 包含非键列 ``` **筛选唯一索引**(仅约束部分数据): ```sql CREATE UNIQUE INDEX IX_Active_Product ON Products (ProductCode) WHERE IsActive = 1; -- 仅约束活跃商品 ``` **修改现有索引为唯一索引**: ```sql -- 先删除原索引 DROP INDEX 名.索引名; -- 重建唯一索引 CREATE UNIQUE INDEX 新索引名 ON 名 (列名); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值