1. 程式人生 > >SQLServer與MySQL約束/索引命名的一些差異總結

SQLServer與MySQL約束/索引命名的一些差異總結

約束是資料庫完整性的保證,主要分為:主鍵/外來鍵/唯一鍵/預設值/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,刪除存在約束的欄位的時候,無需先刪除約束,直接刪除欄位即可

總結

  不管是在哪種資料庫中,對於資料庫中某些自定義的物件的命名方式,你不主動做選擇就會被預設,被預設就意味著很有可能是被動的。
  既有預設值也有自定義的情況下,自動生成的預設的命名往往不利於維護或者無法做到見名知意,
  在符合規則的前提下,儘可能地去做到自定義(主動而不是被動),以便於後期的維護和管理。