約束是數據庫完整性的保證,主要分爲:主鍵/外鍵/惟一鍵/默認值/check等類別,
約束是一個邏輯概念,表示數據的某些特性(不能爲空,惟一,必須知足某些條件等等),索引是一個邏輯與物理概念的結合,邏輯上是一種數據結構,物理上要佔用實實在在的存儲空間。
對於主鍵和惟一鍵約束,在sqlserver中會自動生成惟一索引,sqlserver中的約束和索引是兩個不一樣的對象,約束就是約束,索引就是索引,主鍵/惟一約束經過主鍵/惟一索引實現。
在MySQL中更爲直接,對於主鍵和惟一鍵,直接定義其primary key和unique key的索引屬性便可
在SQL Server和MySQL中,約束與索引在生成的時候,有各自不一樣的規則和命名方式,如下簡單介紹在兩種數據庫中的特色和差別,以及我的的建議。sql
在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中,無論是對於約束或者索引,都強烈建議使用顯式指定名字的方式命名,不使用系統默認生成的(隨機)名字ide
在MySQL中的約束與索引:sqlserver
CREATE TABLE TestTable1
(
Id int auto_increment not null ,
Name varchar(100) ,
Alias varchar (100) ,
CreateDate datetime not null default now(),
LastUpdate datetime,
spa
primary key (Id),
unique key uq_TestTable1_name(Name),
unique key (Alias),
key (Name,CreateDate)
);server
對應的約束信息對象
對應的索引信息blog
1,系統會默認對主鍵/惟一約束建立主鍵/惟一索引,
對於主鍵約束,無論是否顯式給予命名,系統都會忽略這個主鍵名字,使用PRIMARY替代
對於非主鍵約束,若是顯式給予命名,系統會採用這個命名,不然使用字段名來當作索引的名字
2,MySQL中,索引的名字僅限於表級別不重複,庫級別無要求,
也就是說一個庫中不一樣的表,可使用相同的索引名稱,固然這裏並非建議或者支持這種方式的使用
3,對於非空約束,系統都不會爲NOT NULL約束生成約束的名字
4,對於複合索引(多個字段組成),若是沒有顯式命名,會採用第一個字段命名
從這一點來看,未顯式命名的狀況下,沒法作到見名知意,
也就是說看到索引的名字可以大概知道是一個什麼字段的索引,所以在MySQL中,對於非主鍵索引,建議使用顯式命名的方式進行管理
5,刪除存在約束的字段的時候,無需先刪除約束,直接刪除字段便可
索引
總結
無論是在哪一種數據庫中,對於數據庫中某些自定義的對象的命名方式,你不主動作選擇就會被默認,被默認就意味着頗有多是被動的。 既有默認值也有自定義的狀況下,自動生成的默認的命名每每不利於維護或者沒法作到見名知意, 在符合規則的前提下,儘量地去作到自定義(主動而不是被動),以便於後期的維護和管理。