-
SQL Server解惑——对象命名的唯一性小结
关于SQL Server数据库中的对象命名的唯一性问题。例如表、索引、约束等数据库对象,有时候DBA在做数据库维护时,经常要创建对象或重命名对象,此时就会遇到一个问题,对象命名的唯一性问题。虽然是一个小小的问题,估计不少人搞不清,在看文章前,你可以先回答几个问题
1: 表名在数据库是不是唯一? 不同的Schema下,是否可以存在同名的表?
2: 索引名在数据库是不是唯一? 不同的Schema下,是否可以存在同名的表?
3: 其它数据库对象呢? 例如约束、触发器。
那么我们接下来看看实验例子吧,如下所示,AdventureWorks2014数据库中存在命名为“Production.Product”的表
USE AdventureWorks2014;
GO
SELECT * 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
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE 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
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE 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]
GO
CREATE 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 | 不能出现同名对象 | 可以出现同名对象 |
作者:潇湘隐者
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式