有人可以向我解释一下SQL Server如何使用点符号来识别
桌子的位置?我一直认为位置是Database.dbo.Table
但我看到代码有dbo
代替的代码,例如:
DBName.something.Table
有人可以解释一下吗?
答案 0 :(得分:28)
这是一个数据库架构。表的完整三部分名称是:
databasename.schemaname.tablename
对于用户的默认架构,您还可以省略架构名称:
databasename..tablename
您还可以指定链接服务器名称:
servername.databasename.schemaname.tablename
您可以在MSDN上了解有关将标识符用作表名的更多信息:
服务器,数据库和所有者名称称为对象名称的限定符。引用对象时,不必指定服务器,数据库和所有者。可以通过用句点标记其位置来省略限定符。对象名称的有效形式包括以下内容:
server_name.database_name.schema_name.object_name
server_name.database_name..object_name
server_name..schema_name.object_name
...服务器名OBJECT_NAME
database_name.schema_name.object_name
database_name..object_name
schema_name.object_name
object_name
指定所有四个部分的对象名称称为完全限定名称。在Microsoft SQL Server中创建的每个对象都必须具有唯一的完全限定名称。例如,如果它们具有不同的所有者,则在同一数据库中可以有两个名为xyz的表。
大多数对象引用使用三部分名称。默认server_name是本地服务器。默认的database_name是连接的当前数据库。默认schema_name是提交语句的用户的默认架构。除非另行配置,否则新用户的默认架构是dbo架构。
答案 1 :(得分:4)
@Szymon说的是什么。您还应该指出始终模式限定对象引用(无论是表,视图,存储过程等)。不合格的对象引用按以下方式解析:
针对属于当前连接所在的凭据的默认架构的指定名称的对象,探测当前数据库的命名空间。
如果未找到,请探查当前数据库的名称空间,以查找属于dbo
架构的指定名称的对象。
如果对象引用是以名称以sp_
开头的存储过程,则更糟糕的是,因为在解析过程中又添加了两个步骤(除非引用是数据库限定的):上述两个步骤重复,但这次,查看数据库master
而不是当前数据库。
所以像
这样的查询select *
from foo
需要两个名称空间的探测器来解析foo
(假设表/视图实际上是dbo.foo
):首先在默认模式(john_doe.foo
下),然后找不到,在dbo
(dbo.foo
')下,而
select *
from dbo.foo
立即使用命名空间的单个探测器解析。
这有三个含义:
冗余查找费用很高。
它禁止查询计划缓存,因为每次执行都必须重新评估,这意味着必须为每次执行重新编译查询(并且需要编译时锁)。
你会在某一点上射击自己,无意中在dbo
模式下应该存在(也许已经存在)的默认模式下创建一些东西。现在你有两个版本。
在某些时候,您或其他人(通常是在生产中发生)将运行查询或执行存储过程并获得......意外结果。您需要花费相当长的时间来确定同一对象有两个[不同]版本,并且执行哪个版本取决于其用户凭据以及引用是否为模式限定。
除非您有真正的理由不这样做,否则始终是架构资格。
话虽如此,为了开发目的,它有时可能有用,可以在您的个人架构下维护某些东西的“新”版本,并在“dbo”架构下维护“当前”版本。它可以轻松进行并排测试。但是,它并非没有风险(见上文)。
答案 2 :(得分:0)
当SQL看到语法时,它将首先查看当前用户架构以查看该表是否存在,并且如果存在则将使用该表。 如果没有,那么它会查看dbo架构并使用那里的表