關于SQL Server資料庫中的物件命名的唯一性問題,例如表、索引、約束等資料庫物件,有時候DBA在做資料庫維護時,經常要創建物件或重命名物件,此時就會遇到一個問題,物件命名的唯一性問題,雖然是一個小小的問題,估計不少人搞不清,在看文章前,你可以先回答幾個問題
1: 表名在資料庫是不是唯一? 不同的Schema下,是否可以存在同名的表?
2: 索引名在資料庫是不是唯一? 不同的Schema下,是否可以存在同名的表?
3: 其它資料庫物件呢? 例如約束、觸發器,
那么我們接下來看看實驗例子吧,如下所示,AdventureWorks2014資料庫中存在命名為“Production.Product”的表
USE AdventureWorks2014;GOSELECT * FROM sys.objects WHERE OBJECT_ID =OBJECT_ID('Production.Product')
此時創建同名的表,就與遇到“There is already an object named 'Product' in the database.”這個錯誤,如下所示:
CREATE TABLE Production.Product
(
name NVARCHAR(32)
)

另外,如果我將這個表物件創建在默認的Scheme(dbo)下面,那么這個是沒有什么問題的,如下所示:
CREATE TABLE dbo.Product
(
name NVARCHAR(32)
)
結論總結:表名在資料庫是唯一,在同一個Schema下,不允許存在相同的表名,但是不同的Schema下,是可以存在同名的表,這個很好理解,現實生活中很多這樣的例子,例如,大學寢室, 11棟宿舍樓有201命名的寢室, 13棟宿舍樓也有201命名的寢室,
下面我們生成'Production.Product'的腳本,然后修改一下表名為Product_2020,執行腳本時就會遇到約束已經存在的錯誤提示(注意,不會一次性顯示所有約束已經存在的錯誤提示),
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GOCREATE TABLE [Production].[Product_2020](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[Name] [dbo].[Name] NOT NULL,
[ProductNumber] [nvarchar](25) NOT NULL,
[MakeFlag] [dbo].[Flag] NOT NULL CONSTRAINT [DF_Product_MakeFlag] DEFAULT ((1)),
[FinishedGoodsFlag] [dbo].[Flag] NOT NULL CONSTRAINT [DF_Product_FinishedGoodsFlag] DEFAULT ((1)),
[Color] [nvarchar](15) NULL,[SafetyStockLevel] [smallint] NOT NULL,
[ReorderPoint] [smallint] NOT NULL,
[StandardCost] [money] NOT NULL,
[ListPrice] [money] NOT NULL,
[Size] [nvarchar](5) NULL,
[SizeUnitMeasureCode] [nchar](3) NULL,
[WeightUnitMeasureCode] [nchar](3) NULL,
[Weight] [decimal](8, 2) NULL,
[DaysToManufacture] [int] NOT NULL,
[ProductLine] [nchar](2) NULL,
[Class] [nchar](2) NULL,
[Style] [nchar](2) NULL,
[ProductSubcategoryID] [int] NULL,
[ProductModelID] [int] NULL,
[SellStartDate] [datetime] NOT NULL,
[SellEndDate] [datetime] NULL, [DiscontinuedDate] [datetime] NULL,[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_Product_rowguid] DEFAULT (newid()),
[ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_Product_ModifiedDate] DEFAULT (getdate()),
CONSTRAINT [PK_Product_ProductID] PRIMARY KEY CLUSTERED
(
[ProductID] 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
Msg 2714, Level 16, State 5, Line 11
There is already an object named 'PK_Product_ProductID' in the database.
Msg 1750, Level 16, State 0, Line 11
Could not create constraint or index. See previous errors.
如上所示,約束也是唯一的,它跟表名一樣,而且也是跟Schema有關系,如下所示,下面SQL是OK的,
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GOCREATE TABLE [dbo].[Product_2020](
[ProductID] [int] IDENTITY(1,1) NOT NULL,
[Name] [dbo].[Name] NOT NULL,
[ProductNumber] [nvarchar](25) NOT NULL,
[MakeFlag] [dbo].[Flag] NOT NULL CONSTRAINT [DF_Product_MakeFlag] DEFAULT ((1)),
[FinishedGoodsFlag] [dbo].[Flag] NOT NULL CONSTRAINT [DF_Product_FinishedGoodsFlag] DEFAULT ((1)),
[Color] [nvarchar](15) NULL,[SafetyStockLevel] [smallint] NOT NULL,
[ReorderPoint] [smallint] NOT NULL,
[StandardCost] [money] NOT NULL,
[ListPrice] [money] NOT NULL,
[Size] [nvarchar](5) NULL,
[SizeUnitMeasureCode] [nchar](3) NULL,
[WeightUnitMeasureCode] [nchar](3) NULL,
[Weight] [decimal](8, 2) NULL,
[DaysToManufacture] [int] NOT NULL,
[ProductLine] [nchar](2) NULL,
[Class] [nchar](2) NULL,
[Style] [nchar](2) NULL,
[ProductSubcategoryID] [int] NULL,
[ProductModelID] [int] NULL,
[SellStartDate] [datetime] NOT NULL,
[SellEndDate] [datetime] NULL, [DiscontinuedDate] [datetime] NULL,[rowguid] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_Product_rowguid] DEFAULT (newid()),
[ModifiedDate] [datetime] NOT NULL CONSTRAINT [DF_Product_ModifiedDate] DEFAULT (getdate()),
CONSTRAINT [PK_Product_ProductID] PRIMARY KEY CLUSTERED
(
[ProductID] 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
結論:對于任何約束(主鍵約束、外鍵約束、默認約束等),在資料庫中同一個Schema下是唯一的,不允許存在相同的約束名稱,但是不同的Schema下,是可以存在同名的約束,
索引呢,你簡單測驗一下,就會有所發現情況有點不同,
USE [AdventureWorks2014]GOCREATE UNIQUE NONCLUSTERED INDEX [AK_Product_rowguid] ON [Production].[Product_2020]
(
[rowguid] ASC)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
為什么索引物件的唯一性是跟前面表物件有所不同呢,這個說實話,實在沒有看到詳細介紹,只能懷疑是跟SQL Server官方的設定、限制有關系,
SQL Server中可以存在同名的索引嗎? 如果是同一個表呢?
答案:不同的表,可以存在同名的索引,但是同一個表,不能存在同名的索引,
對于觸發器而言,它跟表名、約束一樣的規則, 這里限于篇幅,就不展開了,有興趣的自行測驗一下,
下面將前面的知識用表格總結一下:
|
|
相同Schema下 |
不同Schema下 |
|
Table |
不能出現同名物件 |
可以出現同名物件 |
|
Constraint |
不能出現同名物件 |
可以出現同名物件 |
|
Index |
可以出現同名物件,但是同一個表,不能存在同名的索引 |
可以出現同名物件 |
|
Trigger |
不能出現同名物件 |
可以出現同名物件 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/226440.html
標籤:其他
上一篇:mysql資料庫批量執行sql檔案對資料庫進行操作【windows版本】
下一篇:大資料引擎分代
