sql-spider 是做什麼的?
建立 SQL 資料庫的確定性依賴關係圖,並從一個種子物件向外爬取,直到閉合:一個連通分量、零孤立節點、無幻影邊。圖形引擎是純粹且離線的:它將 SQL 文字解析為 AST,並直接從樹上讀取依賴關係,因此相同的輸入總是產生相同的圖形,無需啟發式演算法,也無需即時連線。
這個技能存在的理由:sql-spider 從不連接到資料庫。 它發出唯讀查詢並匯入 CSV 結果。所以你,代理,就是資料庫適配器。 你以任何可到達資料庫的方式執行每個發出的查詢,將結果反饋回來,並驅動循環。這正是它的構建方式(映射一個只能透過唯讀作業存取的資料庫,永遠無法直接連線),也是為什麼這個工具可以安全地用於任何地方。
何時使用
- 「映射這個資料庫」/「為我建立這些儲存程序 / 資料表 / 檢視表的依賴關係圖。」
- 「什麼東西參考了
Orders?」/「proc_x實際上觸及了哪些東西?」 - 「找出這個資料表的完整閉包」:它傳遞依賴的所有東西,直到沒有任何遺漏。
- 「我無法直接存取資料庫,請發出查詢,我來執行它們」,或「將查詢發送給 DBA。」
- 文件化 / 理解一個沒有人知道什麼依賴於什麼的遺留結構。
不適用於:撰寫應用程式 SQL、變更資料或結構(此技能為唯讀,請參閱防護措施),或任何需要變更資料庫的操作。
運作方式(合約)
引擎與方言無關。唯一與方言相關的步驟是將 .sql 解析為依賴事實(在一個單一方法 IDialectExtractor 背後)。其他所有東西都是方言中立的:圖形組裝、前緣、蜘蛛爬取循環、連通分量閉合稽核、譜系、視覺化。
無論方言或資料庫為何,循環的形狀始終相同:
- 種子 / 回合 將唯讀
.sql查詢檔案發出到一個輸出目錄。 - 你 對著資料庫執行那些查詢(適配器步驟),並將每個結果儲存為 CSV。
- 吸收 將 CSV 折疊回語料庫作為
.sql。 - 回合 重新提取,寫出圖形 + HTML 視覺化,並安排下一輪拉取查詢,或報告閉合。
- 重複直到前緣清空且圖形為一個連通分量。
第一步:安裝,不只是執行(一次性)
如果你透過原始擷取(使用者貼上了 「fetch .../SKILL.md 並遵循它」)或從一個不在你的技能目錄中的簽出到達此檔案,請在使用它之前安裝它,將儲存庫克隆到你的技能目錄中,並從已安裝的副本繼續:
git clone https://github.com/royashbrook/sql-spider ~/.claude/skills/sql-spider # Claude Code
# 其他框架:克隆到你的技能自動發現的任何位置
然後告訴使用者你已安裝它。差異很重要:就地執行(或原始擷取)今天有效但明天會被遺忘;安裝後,每個未來的會話都會自行發現該能力。將「使用此工具」視為包含安裝。
同樣的規則適用於 graphify 配對(步驟 6):graphify 的安裝是兩個命令(uv tool install graphifyy 用於二進位檔,然後 graphify install --platform <your harness> 用於註冊 graphify 自己的技能)。僅安裝二進位檔是最常見的遺漏;兩者都要做。
步驟 0:一次性構建(首次使用時構建)
此技能提供的是 .NET 原始碼,而非二進位檔。第一次呼叫會構建它;之後的呼叫會重複使用構建結果。需要 .NET 10 SDK(dotnet --version;如果沒有,請安裝它:在 macOS 上使用 brew install dotnet,在其他地方使用發行版套件,或 https://dot.net)。
將 SKILL_DIR 解析為包含此檔案的目錄,然後定義一個命令:
SKILL_DIR="<此技能目錄的絕對路徑>"
spider() { dotnet run -c Release --project "$SKILL_DIR" -- "$@"; }
第一次 spider ... 呼叫會編譯(幾秒鐘,還原 ScriptDom + SqlParserCS);之後的每次呼叫都很快。在觸及真實資料庫之前,先用附帶的範例進行健全性檢查:
spider extract "$SKILL_DIR/examples/northwind" # -> 36 個節點,66 條邊,「一個分量,零孤立節點」
spider viz "$SKILL_DIR/examples/northwind/graph.json" && open "$SKILL_DIR/examples/northwind/graph.html"
如果列印出 OK: single connected component, no orphans,則工具正常運作。
步驟 1:選擇適配器(你將如何到達資料庫?)
sql-spider 發出查詢;必須有人執行它們。在播種之前決定你是下列哪一種(完整配方在 references/adapters.md):
- 一個連接的 SQL 工具 / MCP:你有一個執行查詢並返回資料列的工具。你執行每個發出的
.sql並將資料列寫出為 CSV。最快;當代理可以存取資料庫時最佳。 - 一個唯讀查詢橋樑:一個作業/技能,你放入一個
.sql檔案,它會對著資料庫執行,然後一個 CSV 回來(這是原始設定,一個具有讀取權限的 CI 作業)。你透過它分發每個發出的查詢並收集 CSV。 - 使用者執行它們:你完全無法存取資料庫。你列印每個查詢,使用者在他們的用戶端(SSMS、
sqlcmd等)中執行它,並貼回 CSV。最慢,但隨處可用,並且是針對鎖定的生產資料庫的正確作法(使用者或其 DBA 批次執行)。
無論是哪一種,合約都相同:發出的 .sql 進入,CSV 出來。選擇一個並在整個執行過程中保持使用。
步驟 2:設定工作目錄
在技能目錄之外工作,以保持技能儲存庫乾淨。在使用者的專案中(或任何暫存目錄):
mkdir -p work/corpus work/stage && cd work
corpus/ 存放累積的 .sql(到目前為止的模型);stage/ 是這一輪的查詢及其 CSV 所在的位置。
步驟 3:從根物件播種
選擇使用者關心的根物件,一個中心資料表或程序。從它開始冷啟動:
spider seed Orders stage/ # 將唯讀拉取查詢寫入 stage/
seed 發出查詢以拉取根物件本身的定義、其結構(如果是資料表),以及所有參考它的東西。透過你的適配器執行那些查詢(步驟 1),將每個結果儲存為 CSV 到 stage/,然後將它們折疊進來:
spider absorb stage/*.csv --corpus corpus/
步驟 4:循環至閉合(一次一個可審查的回合)
spider round corpus/
每個回合:重新提取 corpus/ 到 corpus/graph.json,寫入 corpus/graph.html(打開它以進行審查),並要么報告閉合,要么在 corpus/_next/ 中安排下一輪拉取查詢。如果還有前緣:
# 透過你的適配器執行 corpus/_next/*.sql,將 CSV 儲存到 corpus/_next/,然後:
spider absorb corpus/_next/*.csv --corpus corpus/
spider round corpus/ # 再次
前緣每輪都會縮小。預設為一次一個回合,以便人類可以打開視覺化並決定是否繼續拉取,特別是在生產環境中。持續進行,直到 round 報告前緣為空。
步驟 5:閉合
當前緣為空且圖形是一個具有零孤立節點的連通分量時,你就完成了。閉合稽核是閘門;extract 在圖形尚未閉合時甚至返回非零退出碼,因此它可以被整合到 CI 中。
一個範圍說明:節點身份是資料庫範圍內的裸名稱(結構描述前綴被移除),因此一次蜘蛛爬取運行映射一個資料庫。如果使用者的問題跨越結構描述或資料庫,每個範圍執行一次循環,使用第一個閉合圖形的邊界邊(指向其外部的參考)作為下一次掃描的種子,然後合併生成的 graph.json 檔案(graphify merge-graphs,或一個小的 json 聯合)。你可以自己驅動整個序列;它不需要新的工具。
並非每個物件都透過邊閉合,這沒關係:一個真正獨立的物件(一個僅供應用程式使用的函數,一個僅從資料庫外部參考的版本/歸檔資料表)會被附帶原因報告,而不是作為錯誤。誠實的不變數是「因提取遺漏而產生的零孤立節點」:當一個節點是孤立的時,稽核會告訴你它是一個需要拉取的真實缺口,還是一個真正的獨立物件。
步驟 6:檢視它,並(可選)移交給 graphify
你已經有了一個檢視器,無需安裝:spider viz <graph.json> 會寫入一個自包含的互動式 HTML(力導向、可拖曳、按種類著色)。在任何瀏覽器中打開它。對於大多數用途,這就是你所需要的全部。
如果 graphify 已安裝,請提供將閉合圖形移交給它的選項。 graphify (https://github.com/safishamsi/graphify) 將圖形轉換為一個可查詢的知識圖譜,具有社群偵測和 query / path / explain 功能。作為代理,檢查它是否可用(PATH 上的 graphify 命令、一個 graphify 技能,或專案中已有的 graphify-out/ 目錄),如果是,詢問使用者是否也要發出 graphify 檢視並移交它。如果未安裝,提供安裝它的選項,如果使用者同意,請安裝兩部分,二進位檔和技能(uv tool install graphifyy,然後 graphify install --platform <your harness>)。第二個命令是讓 graphify 在未來會話中可被發現的關鍵;僅安裝二進位檔是最常見的遺漏。
使用 --graphify,不要將原生的 graph.json 複製到 graphify。 原生圖形是一個有向多重圖;直接交給 graphify 會被低估。--graphify 標誌會寫入一個單獨的、符合 graphify 格式的檔案,並保持原生的 graph.json 不變:
spider extract corpus/ --graphify # 寫入原生 graph.json 和 graphify-out/graph.json
graphify cluster-only corpus/ # 叢集 + 報告(或僅 /graphify)
有兩件值得知道的事情,都是在真實運行中學到的:
- 關係詞彙(預設保留我們的)。 投影預設保留 sql-spider 自己的關係(
fk/references/writes/calls/join_key)。graphify 可以很好地引入它們,而讀取與寫入的分離是「什麼實際上更新了這個資料表」的最有用信號。添加--graphify-standard以收縮到 graphify 的受祝福列舉(references/calls/shares_data_with),這在合併多個資料庫並希望使用一個統一的詞彙時很方便。 - 詢問一個資料表如何使用。 使用 graphify
explain X,而不是query X。一個被參考的資料表是一個接收器(邊向內指向),因此query(向外走訪)只會返回資料表本身,而explain則顯示回答問題的入邊。 - 為社群命名。 叢集會產生佔位標籤(「社群 7」),而一個有 50 多個未命名叢集的圖形對於你交給的人類來說是不可讀的。你幾乎總是能從成員中推斷出一個真實的名稱:主要的資料表名稱前綴、中樞物件,以及叢集中的程序實際上做什麼(帳單、調度、薪資評級、稽核)。在
cluster-only之後,讀取每個社群的成員列表並將其重新命名為一個簡短的、符合領域事實的標籤(在 graphify 的graph.json/ 報告中編輯社群標籤)。十分鐘的命名可以區分出一個擁有者可以導航的圖形和一個只有你能導航的圖形。提供這個選項;人類會同意。
在我們自己的使用中,我們將一個帳單子系統映射到一個閉合圖形,並直接從中回答了「什麼依賴於這個」,只打開了圖形指向的那一個程序。graphify 自己的文件涵蓋了知識圖譜為你帶來的其餘好處。如果 graphify 未安裝,請跳過所有這些;viz 已經顯示了圖形,而 sql-spider 的工作在閉合後就完成了。
防護措施
- 始終唯讀。 每個發出的查詢都是一個
select,帶有無鎖 / 死鎖受害者 /set nocount on安全前綴。切勿將其編輯成寫入操作。切勿透過此技能執行insert/update/delete/merge/ DDL。如果你正在組合任何非唯讀的東西,你就用錯了工具。 - 針對生產環境,控制節奏。 不要自動向生產資料庫發送大量查詢。一次執行一個可審查的回合,或將安排好的查詢交給使用者 / DBA 批次執行。自動循環(
round直到閉合)僅在適配器可以安全地無人值守運行且資料庫擁有者同意時才適合。 - 圖形比主體更安全。 依賴關係圖(物件名稱 + 邊)是持久化的輸出。
corpus/中被拉取的程序主體是目標組織的內部邏輯。將該語料庫視為私有資訊;發布圖形,而不是主體。
子命令
| 命令 | 功能 |
|---|---|
extract <corpus-dir> [graph.json] [frontier.json] [--dialect tsql|sqlite] [--graphify[=out.json]] [--graphify-standard] | 將 *.sql 解析為依賴關係圖 + 前緣 + 稽核;--graphify 也會寫入 graphify 格式的圖形(--graphify-standard 使用 graphify 的受祝福關係詞彙) |
seed <root-object> <outdir> | 在空語料庫上為一個根物件冷啟動拉取查詢 |
generate <frontier.json> <outdir> | 為當前前緣向前拉取查詢 |
reverse <referencers.csv> <outdir> [--roots a b] | 拉取參考根的物件的模組定義(一個反向層級) |
absorb <csv...> --corpus <dir> | 將拉取的 CSV 折疊回語料庫作為 .sql |
viz <graph.json> [out.html] | 將圖形渲染為一個自包含的互動式 HTML 檔案 |
round <corpus-dir> [--dialect ...] | 一次可審查的蜘蛛爬取傳遞:提取 → 圖形 + 視覺化 → 安排下一輪查詢(或報告閉合) |
round 是循環驅動器;其他的是它所組成的部分(以及你在使用 seed 冷啟動或使用 generate / reverse 進行手動傳遞時直接呼叫的部分)。
方言
--dialect tsql(預設)使用 Microsoft ScriptDom 解析(完整的 T-SQL 保真度)。--dialect sqlite 使用 SqlParserCS 解析(它也涵蓋 MySQL / Postgres / 其他)。添加一個方言只需要一個實現 IDialectExtractor 並在 Extractor.Pick 中註冊的小類;引擎保持不變。請參閱 README.md 以了解完整設計和已完成的 Northwind 範例。