跨資料庫的中繼資料
指名別的資料庫(LibArchive.dbo.Loan)時中繼資料怎麼載入。分層與快取的一般規則見 中繼資料。
LibArchive.dbo. 與 LibArchive. 都要另一個資料庫的物件清單,而所有查詢都寫成 不加限定的 sys.objects——換句話說,決定查哪一個資料庫的是連線,不是 SQL。 跨資料庫因此只多一層 SqlDatabaseScopedConnectionSource:它包住查詢視窗那條連線, 開出來之後 ChangeDatabase 到目標資料庫。四層分層、快取、失敗降級一條都不必重寫。
只打一段的 LibArchive. 走的是同一條路,差別在於「這一段是資料庫還是結構描述」 只看文字分不出來,要先經過 SqlQualifierResolver 比對快照裡的名單, 規則見限定名稱。
四件事刻意這樣:
- 只在使用者真的打出資料庫名稱之後才建目錄。 預先把每一個
HAS_DBACCESS進得去 的資料庫都撈一份的話,共用主機上等於幾十輪查詢與幾十份常駐快照,而其中九成九 不會有人用到。代價是第一次打出LibArchive.dbo.要等一輪,但那跑在建議清單的 背景工作上,不在按鍵路徑。 - 跨資料庫的目錄有數量上限,超過就淘汰最久沒用到的。 查詢視窗自己那條連線的 目錄不參與淘汰——那是使用者正在看的資料庫,淘汰它等於下一次按鍵重查一輪。 上限要涵蓋的是「這一段工作裡手邊會提到的資料庫」,不是「這台伺服器上有幾個」。
- 物件記得自己從哪個資料庫來。
SqlObjectInfo.DatabaseName帶在物件身上, 而不是由呼叫端一路傳下去:滑鼠停留提示、結構預覽、F12、提交後展開都會拿著一個SqlObjectInfo回頭要第二、三、四層,各自記一份就是五份會忘記更新的狀態。 這件事非做不可的理由是object_id只在自己那個資料庫裡唯一:不換目錄就會 拿到另一個資料庫裡剛好同號的那個物件的欄位,而欄位清單看起來完全正常。 - 載入失敗之後隔一段時間才再試。 失敗刻意不進快取(否則連線恢復之後仍然拿到 空的),而空快照永遠不算新鮮——兩條加起來,連不上的目標就是每按一次鍵重開一條 連線,且每一次都要等滿命令逾時。使用者看到的是打字整個卡住。按重新整理會清掉 退避:那個動作就是在說「我修好了」。
沒有為這個功能加設定。不打跨資料庫名稱的人不會建立任何跨資料庫的目錄,也不會多 一次查詢——不用時就沒有成本的東西加開關,只會多一個沒有人會動的旋鈕,而每一個 設定都要動四處並過守門測試。要整個關掉的人本來就有「列出資料庫物件與欄位」。