約束是數據庫完整性的保證,主要分為:主鍵/外鍵/唯一鍵/默認值/check等類別,
約束是一個邏輯概念,表示數據的某些特性(不能為空,唯一,必須滿足某些條件等等),索引是一個邏輯與物理概念的結合,邏輯上是一種數據結構,物理上要占用實實在在的存儲空間。
對於主鍵和唯一鍵約束,在sqlserver中會自動生成唯一索引,sqlserver中的約束和索引是兩個不同的對象,約束就是約束,索引就是索引,主鍵/唯一約束通過主鍵/唯一索引實現。
在MySQL中更為直接,對於主鍵和唯一鍵,直接定義其primary key和unique key的索引屬性即可
在SQL Server和MySQL中,約束與索引在生成的時候,有各自不同的規則和命名方式,以下簡單介紹在兩種數據庫中的特點和差異,以及個人的建議。
在SQL Server中的約束與索引:
CREATE TABLE TestTable1
(
--1,系統會默認對主鍵/唯一約束創建主鍵/唯一索引,索引的名字會與約束的名字一致
Id int identity(1,1) not null constraint pk_Id primary key (Id),
Name varchar(100) constraint uq_testtable1_name unique,
--2,對主鍵/唯一約束,如果沒有指定約束的名字,按照某種規則+隨機生成索引名字
Alias varchar (100) unique,
CreateDate datetime not null constraint df_createdate default getdate(),
--3,對於非空約束,不管是否指定了約束的名稱,系統都不會為NOT NULL約束生成約束的名字
LastUpdate datetime constraint notnullconstraint not null
)
1,系統會默認對主鍵/唯一約束創建主鍵/唯一索引,索引的名字會與約束的名字一致
2,對主鍵/唯一約束,如果沒有指定約束的名字,按照某種規則+隨機的方式生成索引名字
3,對於非空約束,不管是否指定了約束的名稱,系統都不會為NOT NULL約束生成約束的名字
4,約束或者索引的名字,在數據庫級別是唯一的,也就是說A表的約束的名字不能跟B表的約束采用同一個名字,對於索引,是表級別唯一的。
5,在sqlserver中,如果刪除一個存在約束的字段,必須要先刪除約束,否則報錯,參考下圖
如果讓約束隨機命名,刪除約束的時候會比較麻煩,所以建議對於約束要顯式命名,sqlserver中,不管是對於約束或者索引,都強烈建議使用顯式指定名字的方式命名,不使用系統默認生成的(隨機)名字
在MySQL中的約束與索引:
CREATE TABLE TestTable1
(
Id int auto_increment not null ,
Name varchar(100) ,
Alias varchar (100) ,
CreateDate datetime not null default now(),
LastUpdate datetime,
primary key (Id),
unique key uq_TestTable1_name(Name),
unique key (Alias),
key (Name,CreateDate)
);
對應的約束信息
對應的索引信息
1,系統會默認對主鍵/唯一約束創建主鍵/唯一索引,
對於主鍵約束,不管是否顯式給予命名,系統都會忽略這個主鍵名字,使用PRIMARY替代
對於非主鍵約束,如果顯式給予命名,系統會采用這個命名,否則使用字段名來當做索引的名字
2,MySQL中,索引的名字僅限於表級別不重復,庫級別無要求,
也就是說一個庫中不同的表,可以使用相同的索引名稱,當然這里並不是建議或者支持這種方式的使用
3,對於非空約束,系統都不會為NOT NULL約束生成約束的名字
4,對於復合索引(多個字段組成),如果沒有顯式命名,會采用第一個字段命名
從這一點來看,未顯式命名的情況下,無法做到見名知意,
也就是說看到索引的名字能夠大概知道是一個什么字段的索引,因此在MySQL中,對於非主鍵索引,建議使用顯式命名的方式進行管理
5,刪除存在約束的字段的時候,無需先刪除約束,直接刪除字段即可
總結
不管是在哪種數據庫中,對於數據庫中某些自定義的對象的命名方式,你不主動做選擇就會被默認,被默認就意味着很有可能是被動的。
既有默認值也有自定義的情況下,自動生成的默認的命名往往不利於維護或者無法做到見名知意,
在符合規則的前提下,盡可能地去做到自定義(主動而不是被動),以便於后期的維護和管理。