web-dev-qa-db-ja.com

SQLドット表記

SQL Serverがドット表記を使用して識別する方法を誰かに説明してもらえますか
テーブルの場所は?いつも場所はDatabase.dbo.Table
しかし、次のようなdboの代わりに他の何かがあるコードが表示されます。
DBName.something.Table誰かがこれを説明できますか?

14
user2343837

これはデータベーススキーマです。テーブルの完全な3部構成の名前は次のとおりです。

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

server_name ... object_name

database_name.schema_name.object_name

database_name..object_name

schema_name.object_name

object_name

4つの部分すべてを指定するオブジェクト名は、完全修飾名と呼ばれます。 Microsoft SQL Serverで作成される各オブジェクトには、一意の完全修飾名が必要です。たとえば、所有者が異なる場合、同じデータベースにxyzという名前の2つのテーブルが存在する可能性があります。

ほとんどのオブジェクト参照は3部構成の名前を使用します。デフォルトのserver_nameはローカルサーバーです。デフォルトのdatabase_nameは、接続の現在のデータベースです。デフォルトのschema_nameは、ステートメントを送信するユーザーのデフォルトのスキーマです。特に設定されていない限り、新しいユーザーのデフォルトのスキーマはdboスキーマです。

30
Szymon

@Szymonが言ったこと。また、alwaysスキーマ修飾オブジェクト参照(テーブル、ビュー、ストアドプロシージャなど)をポイントする必要があります。修飾されていないオブジェクト参照は、次の方法:

  • 現在の接続が実行されている資格情報のデフォルトのスキーマに属する指定された名前のオブジェクトについて、現在のデータベースの名前空間をプローブします。

  • 見つからない場合は、現在のデータベースの名前空間を調べて、dboスキーマに属する指定された名前のオブジェクトを探します。

オブジェクト参照がsp_で始まる名前のストアドプロシージャへの参照である場合、解決プロセスにさらに2つのステップが追加されるため(参照がデータベース修飾されていない限り)、上記の2つのステップが繰り返されます。今回は、現在のデータベースではなくデータベースmasterを調べます。

したがって、次のようなクエリ

select *
from foo

fooを解決するには、名前空間の2つのプローブが必要です(テーブル/ビューが実際にはdbo.fooであると想定):最初にデフォルトのスキーマ(john_doe.foo)の下にあり、次に見つかりませんdbodbo.foo ')、

select *
from dbo.foo

名前空間の1つのプローブですぐに解決されます。

これには3つの意味があります。

  1. 冗長なルックアップは高価です。

  2. すべての実行を再評価する必要があるため、クエリプランのキャッシュが抑制されます。つまり、実行ごとにクエリを再コンパイルする必要があります(これにより、コンパイル時のロックが解除されます)。

  3. ある時点で別の時点で足元を撃ち、デフォルトのスキーマの下にdboスキーマの下に存在するはずの(おそらくすでに存在している)何かを誤って作成します。これで、2つのバージョンが浮かんでいます。

    ある時点で、あなたまたは他の誰か(通常は本番環境で発生します)willクエリを実行するか、ストアドプロシージャを実行して予期しない結果を取得します。同じオブジェクトの2つの[異なる]バージョンがあり、どれが実行されるかは、ユーザーの資格情報と、参照がスキーマ修飾されているかどうかによって異なります。

本当の理由がない限り、常にスキーマ修飾します。

そうは言っても、開発の目的で、個人スキーマの下にある「新しい」バージョンと「dbo」スキーマの下にある「現在の」バージョンを維持できると便利な場合があります。サイドバイサイドテストを簡単に実行できます。ただし、リスクがないわけではありません(上記参照)。

4
Nicholas Carey

SQLが構文を見ると、まず現在のユーザーのスキーマを調べてテーブルが存在するかどうかを確認し、存在する場合はそのスキーマを使用します。そうでない場合は、dboスキーマを調べ、そこからテーブルを使用します

0
yogeshwar gutte