我正在閱讀 Neo4j,一個圖形資料庫,以及它與關系模型的比較。這里有一件事是在如何查詢M2M連接與單個用戶相關聯的“部門”提到
我想,如果我事先知道我只是逐行查找單行 PK 并且該用戶可能少于 5 個部門,我會按如下方式撰寫查詢:
SELECT name FROM department WHERE department_id IN (
SELECT department_id FROM PersonDepartment WHERE user_id IN (
SELECT pk FROM Person WHERE name='Alice' # assume unique name
)
)
我確信以更常見的“連接格式”撰寫它會被 RDBMS 優化為更接近于上面的內容,但我使用上面的只是為了展示上面的查詢似乎幾乎不需要時間來執行,還是我錯了?另一方面,以更簡潔的 Cypher 格式撰寫上述內容:[p:Person{name:"Alice"}]-[:BELONGS_TO]->[d:Department]更易于閱讀和撰寫。
uj5u.com熱心網友回復:
初步的
把一些混淆問題的問題排除在外,以便我們可以直截了當地回答問題。
圖形中的文字模糊
- 這是完全不誠實的,典型的稻草人論點,用來貶低他所反對的,并提升他所支持的。他將關系方法視為它不是的東西(1960 年代的記錄歸檔系統,帶有
IDs“主鍵”),然后將其取下 - 哎呀,他毀了自己的混合物,他的稻草人
- 關系方法保持不變,不受影響
- 然而,未受過教育的人會感到困惑。
- 這是完全不誠實的,典型的稻草人論點,用來貶低他所反對的,并提升他所支持的。他將關系方法視為它不是的東西(1960 年代的記錄歸檔系統,帶有
ID作為“主鍵”
的欄位關系模型明確禁止IDs,它們是物理的。PK 必須“由資料組成”,這是邏輯的。- 此外,該檔案包含重復的行(
IDs不提供行唯一性,這是RM要求的) IDs使 DML 代碼復雜化,并JOINs在構建稻草人時強制執行更多(在等效的關系資料庫中不需要),親愛的教授所指望的- 在
IDs需要拆除,并實施適當的關系需要鑰匙 - 邏輯的關系完整性(與物理的參照完整性不同)丟失了,不可能
- 書籍圖的關系模式中的完整詳細資訊。
- 此外,該檔案包含重復的行(
沒有頭腦的人會以這種方式遍歷這三張桌子,更不用說開處方了。
- 他正在使用程序代碼,例如在 a 中
CURSOR,這是反關系的,而且速度非常慢 - 在RM和SQL是基于集合理論,所以在使用一套動詞,比如
SELECT,只有你所需要的選擇 - 命題是一個單一的集合,一個單一的
SELECT滿足它。
- 他正在使用程序代碼,例如在 a 中
問題
我想,如果我事先知道我只是逐行查找單行 PK 并且該用戶可能少于 5 個部門,我會按如下方式撰寫查詢:...
當然不。即使與IDs
- 每個表中的人口是不相關的(PK有一個唯一的索引)
- 讓我們假設 10,000 人;10,000 個部門;16,000,000 人部門
- 在建模或撰寫 DML 代碼時永遠不應考慮性能
- 只有在某些代碼性能不佳時才應考慮它,以期對其進行改進。
除了為了澄清您的問題之外,可以忽略該代碼。
我確信以更常見的“連接格式”撰寫它會被 RDBMS 優化
是的。
使用真正的 SQL 平臺,它將在許多層面上重新優化許多事情:決議;確定查詢計劃;統計的考慮;等等。
使用免費軟體“SQLs”,它做了一個米老鼠版本(最好的情況),而根本沒有(最壞的情況)。這就是為什么到處都在考慮性能,但這是不正常的;不合標準。
更接近于上述內容
當然不。那是狗的早餐。它將創建一個非常優雅和優化的查詢計劃,然后是一個分層的查詢樹(運行時可執行檔案,可以共享)。
但我使用上面的只是為了顯示上面的查詢看起來幾乎不需要時間來執行,或者我在這里錯了嗎?
不,你是對的。從某種意義上說,無論是在 RFS 上運行的可怕代碼示例,還是在關系資料庫上運行的正確代碼,都將在毫秒內執行,“幾乎沒有時間”。
關系資料模型
如果你想評估他在他的提議中的意圖(愛麗絲為哪些部門作業),沒有他的稻草人的不誠實,使用關系資料庫(沒有IDs,正確的關系鍵),我們需要一個資料模型。

- 我所有的模型都在IDEF1X中呈現,這是唯一的關系資料建模標準。(不能使用 ERD。)
- 該IDEF1X介紹是必不可少的讀物。
代碼很簡單。
SELECT NameFirst,
DepartmentCode
FROM Person P
JOIN Employee E ON P.PersonNo = E.EmployeeNo
WHERE NameFirst = "Alice"
This code may produce is more meaningful result set, it is stil a single, simple SELECT.
SELECT NameLast,
NameFirst,
D.Name,
EmploymentDate
FROM Person P
JOIN Employee E ON P.PersonNo = E.EmployeeNo
JOIN Department D ON E.DepartmentCode = D.DepartmentCode
WHERE NameFirst = "Alice"
Comments
One question regarding the "no IDs, proper keys" -- doesn't the PersonNo act the same way as would an autoincrementing PK to identify a person?
Yes.
Except that AUTOINCREMENT/IDENTITY columns have horrendous maintenance problems, thus we do not allow them in Production, thus we do not allow them in Development that is not intended for Production.
The alternative for an INSERT is:
...
PersonNo = (
SELECT MAX( PersonNo ) 1
FROM Person
)
...
- Of course, for high performance OLTP, there are other methods.
- Never use the Oracle method, which is a file of records, each holding a next-sequential-number for some other file.
如果我們使用 PK 必須“由資料組成”并且沒有 SS# 或一些唯一識別人的代碼,那么它只會組合一堆東西:名字 姓氏 出生地 出生日期(或其他任何東西)組合將提供足夠的粒度以保證唯一性)
是的。IDEF1X 簡介中有詳細回答,請閱讀。
簡答...
- 這是一個真正的代理,而不是一個
RecordID(被錯誤地稱為代理)。 - 唯一的理由是當
- 自然 PK 太長(這里有 7 列和 120 多個位元組),無法作為 FK 進入下級表,
并且 - 該表是資料層次結構的頂部,因此不會受到Codd關系模型中規定的訪問路徑獨立性破壞。這在此處的用法中是正確的。
- 自然 PK 太長(這里有 7 列和 120 多個位元組),無法作為 FK 進入下級表,
從技術上講,代理或RecordID) 違反了關系鍵范式。正確放置的代理不會違反訪問路徑獨立規則(沒有超出要訪問的違反),而 aRecordID總是會。用戶看不到代理或RecordID,因為它不是資料。
另外,請注意 (LastName, FirstName, Initial, Birthdate, BirthCountry, BirthState, BirthPlace ) 是用于識別個人的既定國際公約(不是一個標準)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/400990.html
上一篇:如果條件為假,則添加空行
