SQL Serverの同義語が登場する前は、誰もがデータベースエクスペリエンスを簡素化および強化したいと考えていました。
同じサーバーから別のデータベースを参照するデータベースを備えたアプリケーションがあるとします。次に、大規模な再編成により、チームは他のデータベースを別のサーバーに転送する必要があります。
アプリケーションが壊れることは間違いありません。しかし、その場合はどうしますか? 2台のサーバーをリンクし、すべての参照を(再度)ハードコーディングして、新しいサーバーを指すようにしますか?
必要に応じてそれを行うことができ、それへの参照が数個または数十個しかない場合は忘れることができます。ただし、別の転送または名前変更が発生した場合は、同じ悪夢を繰り返す必要があります。
それでも、これに対処するためのより良い方法があります。
SQLServerシノニムの紹介
SQL Serverシノニムで何ができるかを説明する前に、それらが何であるかを説明しましょう。
話し言葉や書き言葉の同義語は、別の単語やフレーズと同じ意味を持つ単語やフレーズを指します。つまり、ゴージャスという言葉 beautifulの同義語です および魅力的 。
単語やフレーズの同義語について私たちが知っていることと同様に、SQL Serverの同義語は、ローカルサーバーまたはリモートサーバーにあるデータベースオブジェクトの代替名を指します。詳しくはこちらをご覧ください。
次の事実からわかるように、SQLServerシノニムを使用するとアプリケーションのメンテナンスがはるかに簡単になります。
それでは、始めましょう!
1。 SQL Serverの同義語は、ベースオブジェクトの転送または名前の変更時に作業を簡素化できます
まず、データベースを別のサーバーに移動したり、何らかの理由で名前を変更したりするときに、コードを変更する手間を省くことができます。この投稿の冒頭で述べたシナリオを参照してみましょう。
大規模な再編成により、チームは mydatabase2内のすべてのオブジェクトへの参照を変更する必要があります prodserver2.mydatabase2。に
したがって、 sys.sql_modulesにクエリを実行します mydatabase2がすべて出現する場合 mydatabase1から 。
USE mydatabase1
GO
SELECT
b.name
,a.definition
,b.type_desc
FROM sys.sql_modules a
INNER JOIN sys.all_objects b on a.object_id = b.object_id
WHERE a.definition like '%mydatabase2%'
GO
これで、上記のスクリプトの出力に、 mydatabase2への参照を持つすべてのオブジェクトが一覧表示されます。 。いいですねそして、これは実行しなければならない作業の範囲を定義するのに役立ちます。
しかし、それはほんの始まりに過ぎません。また、クライアントアプリにコードがあるかどうか、またはデータベースの外部で同じものを参照する他のコードがあるかどうかを確認する必要があります。
影響を受けるコードの量は、新しい問題の大きさを示しています。
さて、ここにそのスクリプトで何が起こっているかについてのいくつかのちょっとした情報があります:
- sys.sql_modules ビュー、ストアドプロシージャ、関数などのSQL定義モジュールであるSQLオブジェクトを含めます。
- 名前 列はオブジェクトの名前です。
- オブジェクトのSQLコードは定義にあります sys.sql_modulesの列 。
- sys.all_objects テーブルやビューなど、データベース内のすべてのオブジェクトを含めます。
- type_descを使用しました オブジェクトのタイプ(ビュー、ストアドプロシージャなど)を判別するための列
- 場所 句は、 mydatabase2への参照を含むSQLコードのクエリをフィルタリングします 。
- 上記のスクリプトを使用して満足のいく結果を得るには、すべてのオブジェクトに対する権限が必要です。これについては、データベース管理者または同様の役割を持つ人に確認してください。これもチェックしてください。
作業の範囲を取得する方法がわかったので、次はそれを修正します。
このコードの混乱を修正して、二度と起こらないようにする方法
わかった。告白します。
SQL Serverの同義語を使用すると、問題が最小限に抑えられるだけで、問題が解消されるわけではありません。
邪魔にならないので、ここに朗報があります。シノニムを使用する前にリモートオブジェクトへの参照が10個ある場合は、10個すべてを変更します。ただし、そのリモートオブジェクトのシノニムの使用を開始すると、10回のオカレンスを変更する代わりに、変更するのは1つだけです。これ以上はありません。
さて、同義語を使用してこれを修正する手順は次のとおりです。
- 各リモートオブジェクトの同義語を作成します。したがって、 prodserver2.mydatabase2.schema1.object1の代わりに 同義語を使用して参照できます。
- 各オブジェクトへの参照を同義語に変更します。
後で、これを行う方法の詳細を確認します。
要点:
シノニムは、データベース、クライアントアプリ、またはその他の場所に関係なく、コードの任意の部分からベースオブジェクトへの参照を保護するための抽象化レイヤーを提供します。そのため、オブジェクトの転送であろうと名前の変更であろうと、別の変更が発生したときに喜ぶことができます。
2。ほとんどのオブジェクトのSQLServerシノニムを作成できます
次に、どのオブジェクトが同義語を持つことができるかを理解しましょう。
- テーブル
- ビュー
- ストアドプロシージャ
- 機能
オブジェクトタイプがわかったので、シノニムで何ができるかがわかるかもしれません。もっと具体的にしましょう。
3。オブジェクトシノニムに適切なコマンドを発行できます
第三に、オブジェクトタイプごとにいくつかの特定のコマンドがあります。
テーブル
テーブルに対してSELECT、INSERT、UPDATE、およびDELETEを実行できるのと同じくらい、そのシノニムに対しても同じことを実行できます。
したがって、代わりに:
SELECT * FROM prodserver2.mydatabase2.schema1.table1
次の変更に耐えられる短いバージョンを使用できます:
SELECT * FROM synonym1
これが当てはまるので、これを行うこともできます:
UPDATE synonym1
SET column1 = <value>
INSERTとDELETEについても同じことが言えます。
ただし、次の点に注意してください。
- シノニムを介して新しいレコードを挿入すると、ベーステーブルに新しいレコードが追加されます。この場合、 prodserver2.mydatabase2.schema1.table1 。
- 更新と削除は同じ効果があります。
これまで、DMLコマンドのみを示してきました。 DROPのようなDDLコマンドはどうですか?
残念ながら、それらを実行することはできません。理由は次のとおりです。
シノニムを削除しても、ベーステーブルは削除されません。同義語を削除します。これについては後ほど詳しく説明します。
ただし、SQLServerのテーブルの同義語に対して実行できるもう1つのことはJOINです。
これはどれほど便利ですか?これを発行する代わりに:
SELECT
a.column1
,b.column1
FROM table3 a
INNER JOIN prodserver2.mydatabase2.schema1.table1 b on a.id = b.id
これを実行できます:
SELECT
a.column1
,b.column1
FROM table3 a
INNER JOIN synonym1 b on a.id = b.id
それはもっと簡単ですか?確かに!
ストアドプロシージャ
ストアドプロシージャの同義語で実行できる関連コマンドの1つは、EXECです。
したがって、次のようなリモートプロシージャを呼び出す代わりに:
EXEC prodserver2.mydatabase2.schema1.spProcedure1
上記の手順の同義語を作成できます。それをsynProcedure1と呼びましょう 。そして、次のように呼び出します:
EXEC synProcedure1
続けましょうか。 VIEWとFUNCTIONでもほとんど同じことができます。もちろん、必要な権限がある場合。ただし、最初に、SQLServerシノニムを作成する方法について説明しましょう。
4。 CREATEを使用したSQLServerシノニムでクエストを開始できます
同義語を作成する方法に到達しました。テーブルにT-SQLを使用してこれを行う方法は次のとおりです。
CREATE SYNONYM synonym1 FOR prodserver2.mydatabase2.schema1.table1
ただし、この警告に注意してください:
mydatabase2.schema1.table1の存在と許可を確認しています prodserver2で 実行時まで延期されます。
つまり、次の場合はわかりません。
- 2台のサーバー( prodserver1 およびprodserver2 )はすでにリンクされています。
- データベースmydatabase2 、スキーマ schema1 、およびテーブル table1 実際に存在します。
- これらのリソースへのアクセスは許可されています。
したがって、同義語を作成した後、機能すると予想されるコマンドを実行して同義語をテストします。
また、ストアドプロシージャ、ビュー、および関数を使用する場合は、同じように動作する必要があります。
しかし、それだけではありません。同義語を作成できる場合は、次を使用して削除することもできます:
DROP SYNONYM synonym1
また、もう1つの注意点があります。同義語はいつでも削除できるため、削除された同義語への参照は実行時にのみチェックされます。
したがって、同義語を削除する前に、 sys.sql_modulesを確認してください。 それへの参照がある場合のために。
SQL Server Management Studio(SSMS)を使用したシノニムの作成と削除
これまで、T-SQLを使用してSQLServerシノニムを作成および削除してきました。同じことを行うときは、グラフィカルインターフェイスを使用することをお勧めします。
ボールを転がしてみましょう。
同義語の作成
コマンドを入力することがあなたの目的ではない場合、同義語を作成する際に従うべき手順は次のとおりです。
- SSMSを実行し、SQLServerにログインします。
- シノニムを作成するデータベースを探します。
- 拡張します。
- 同義語を右クリックします フォルダを選択し、新しい同義語を選択します 。
- 名前、スキーマなど、同義語に必要な情報をフォームに入力します。
- [ OK]をクリックします 。
以下は、SSMSのフォームのスクリーンショットです:
同義語の削除
好みについて言えば、同義語を作成するためのコマンドを入力するのは私のようなものです。ただし、コマンドを入力するよりも、自由に削除する方が簡単です。もちろん、それは私の好みです。とにかく、同義語を削除するときに従う手順は次のとおりです。
- SSMSを実行し、SQLServerにログインします。
- 削除する同義語が存在するデータベースを探します。
- 拡張します。
- 同義語を拡張します フォルダ。
- 削除する同義語を探します。
- 削除する同義語を右クリックして、削除を選択します 。
- [ OK]をクリックします 。
上記の手順を要約するには、ドロップする同義語を右クリックして、[削除]を選択します。 最後に、[ OK]をクリックします 。
以下は、削除を確認する前に表示されるウィンドウのスクリーンショットです。
5.SQLServerシノニムを保護できます
GRANT、DENY、またはREVOKEを使用して、同義語へのアクセスを制御できます。
シノニムsynonym1にSELECT権限を付与するには testuserという名前のユーザーに 、次のようにします:
GRANT SELECT ON synonym1 to testuser
シノニムに追加またはシノニムから削除できるその他の権限は次のとおりです。
- 制御
- 実行
- 更新
- 挿入
- 削除
- 定義を表示
- 所有権を取得する
6。そのテーブル、ビュー、または手順が見つかりませんか?同義語かもしれません
チームの新参者が経験する可能性のある問題の1つは、テーブル、ビュー、手順、または機能の「欠落」です。もちろん、SELECTがオブジェクトに対して発行される場合、それはテーブルまたはビューである可能性があります。しかし、彼はそれをテーブルリストまたはビューリストで見つけることができません。また、以前にSQL Serverの同義語を使用したことがない場合は、それが追加の問題になります。
オリエンテーションの欠如、ドキュメントのギャップ、または標準のギャップを整理することができます。これは、同義語のリストとその基本オブジェクトを新しいチームメンバーに提示するのに役立つ気の利いたスクリプトです。
SELECT
a.[name]
,a.[base_object_name]
,OBJECTPROPERTYEX(OBJECT_ID(a.[name]), 'BaseType') as BaseType
,b.type_desc
FROM sys.synonyms a
INNER JOIN (SELECT DISTINCT type, type_desc from sys.all_objects) b on
CONVERT(varchar(2),OBJECTPROPERTYEX(OBJECT_ID(a.[name]), 'BaseType')) = b.type
「行方不明」のオブジェクト?同義語の場合はもうありません。
ただし、このスクリプトの実行に興奮する前に、考慮すべき点がいくつかあります。
- sys.synonyms ここで、すべてのSQLServerシノニムが現在のデータベースで定義されます。
- タイプとタイプの説明(タイプ)を取得しました およびtype_desc それぞれ) sys.all_objects 。サブクエリで結合する以外のより良いアイデアがあれば、私に知らせてください。
- OBJECTPROPERTYEX テーブル、ストアドプロシージャなどの場合、ベースオブジェクトのタイプを取得するために使用されます。
- 最後に、このスクリプトを実行して目的の出力を取得するために必要な最小限の権限がない場合は、DBAまたは同様の役割を持つ誰かと友達になるときです:)
しかし、疑問に思われるかもしれませんが、うまく機能しないのに、なぜこれらすべてを行うのでしょうか?
7。 SQL Serverの同義語はパフォーマンスに影響しますか?
これは一般的な懸念事項です。そして、舞台裏で何が起こっているのかを具体化するために、実行計画で何が起こるかについての要約を見てみましょう:
- シノニムを使用して最も単純なコードを実行する場合(例:Synonym1のSELECT *)、SQLServerはバインディングフェーズに入り、ベースオブジェクトがシノニムを置き換えます。
- 次に、ベースオブジェクトに対してコマンドを実行するための最適な最適化計画が何であれ、それは同じです。
上記の2つのステートメントに関するいくつかの質問と回答を次に示します。
- SQL Serverはバインドフェーズをどのくらい実行しますか?答え:それほど時間はかかりません。通常、瞬く間に発生します。
- 次のステップでベースオブジェクトと同じ最適化計画を使用し、ベースオブジェクトへのクエリが「十分に高速」である場合、速度は遅くなりますか?回答:いいえ、同じ実行プランを使用するためです。
- 新しいサーバーからの認証はどうですか?回答:データベースの新しいサーバーへの転送によってわずかな遅延が発生した場合、それらは同義語によるものではありません。シノニムを使用して呼び出すか、 server.database.schema.objectをハードコーディングした場合のクエリパフォーマンス 同義語はベースオブジェクトの単なる代替名であるため、同じである必要があります。ベースオブジェクトのパフォーマンスの低下を解決します。
しかし、私の言葉を信じないでください。クエリ実行プランと実際のパフォーマンスで自分で確認する必要があります。
結論
全体として、SQL Serverの同義語に関するほとんどの情報を取り上げたので、要約しましょう。
まず、同義語は、オブジェクト名の変更や転送からあなたを救う単なる代替名です。次に、シノニムの適切な候補は、テーブル、ビュー、ストアドプロシージャ、および関数です。次に、シノニムからそのベースオブジェクトに適切なコマンドを実行できます。あなたもそれを確保することができます。次に、同義語のリストを表示する必要がある場合は、 sys.synonymsがあります。 あなたを助けること。最後に、ベースオブジェクトにパフォーマンスの問題がなければ、パフォーマンスはそれほど問題にはなりません。
では、今日試してみませんか?
どう思いますか?コメントでお知らせください。