2013-01-07 49 views
1

嗯,我不太瞭解數據庫架構,但我真的不明白CTO的想法,但他堅持使用字符作爲 列的類型我們使用的所有表的主鍵。 但主鍵仍然像這樣 - > 1,2,3 ...等。它們是數字。 所以我使用整數+ auto_increment合成PK使用主鍵值字符「1」而不是int值1

但CTO說這是壞bc他不能發出查詢使用LIKE條件上PK?!

  1. 對PK使用角色是否正常,特別是當你的PK是數字時?
  2. 在PK上使用類似條件是否正確?

PS - 因此而不是自動遞增/觸發器,序列CTO問題選擇查詢獲取 從表中最大的價值,他補充道1,然後他那個值轉換成字符串 然後將其存儲。

編輯
謝謝你的幫助!但我需要說服他,這將是一場災難。 我只被教過這個(在這種情況下,角色4 PK)是一個壞主意。 他的論點是...
1.角色PK不會佔用太多空間。
2.數據庫查詢優化器將不得不如果使用整型PK 重新閱讀您的查詢,因爲你會發出類似
"select * from employee where name like 'somename'

Select * from employee where id = 6
因爲where子句更改。
他強烈主張我們使用的是類似
"select * from employee where @columnName like @value"
他說這樣,查詢優化器會運行得更好。

我該如何證明或給他一些有效的理由來改變主意?

謝謝:)

+3

首席技術官顯然是一個白癡! –

+2

我同意米奇。雖然我會避免整個PK /代理 - PK參數,但是如果CTO希望對所有數值使用「LIKE」,爲什麼不只是設置具有適當索引的計算CHAR-ISH列呢? – 2013-01-07 03:08:11

+0

當然。告訴她來這裏讀。他是個白癡。最有可能的是「我是政治型」的CTO,否則他們會在櫃檯做漢堡王的職業生涯 - 顯然,IT技能不是太明智。 – TomTom

回答

4

很多原因導致您的CTO在做出該決定時犯了錯誤;讓我介紹幾個:

  1. 正如您所指出的那樣,你必須採取額外的步驟來生成新的自動遞增的主鍵。這是一個計算成本,它也增加了它在未來某個時間點不一致的可能性。

  2. 一旦超過4個字符(換句話說,12345比「12345」便宜很多),磁盤空間中的字符將花費更多。

  3. 如果你正在使用你的主鍵(這是一些RDBM的默認值)聚集索引,排序的字符是比排序整數完全不同:

特點:1,10, 101,11,12,13,14,15 ... 數字:1,2,3,4 ...

如果您將最大數值作爲字符插入,則會碎片化索引。不是一個無法克服的問題,但更多的是浪費計算能力來清理。至於你關於在PRIMARY KEY上使用LIKE的第二個問題,我不能想到你爲什麼要這樣做的原因;如果您需要LIKE的強大功能,通常是因爲您已經爲用作PRIMARY KEY的列指定了某種重要性,這意味着您需要將其暴露給最終用戶。如果是這種情況,那麼我會使用代理自動遞增數字主鍵,並向用戶公開某種形式的ID。

+0

+1。 「如果你需要LIKE的力量,通常是因爲你已經爲用作PRIMARY KEY的列指定了某種重要性,這意味着你需要將它暴露給最終用戶。如果是這樣的話,那麼我會使用代理自動遞增的數字主鍵,並向用戶展示某種形式的ID。「 - 發現。 (這是我在OP對我的評論中暗示的) –

1

1:是的,沒關係。也可以總是在汽車裏每小時行駛10英里。這輛車不會分解。 Chars(或varchars)在任何比較中都比較慢,因此對於相同的性能,結果是需要較大的預算。他們浪費空間,他們很慢。我建議你在這裏做唯一明智的事情 - 找一份不是白癡的工作。

2:甚至沒有確定。看,這裏的問題是 - 這很可能只是你不能使用的東西。如:數據庫不允許。我真的從來沒有嘗試過 - 我也不會嘗試以每小時100英里的速度撞擊一塊混凝土塊,以確定它是否會損壞汽車。這只是沒有意義。

您的首席技術官顯然需要休假和閱讀一本書。可能有人應該與首席執行官談話並將他送到這裏 - 他對CTO的立場感到白癡。

有爭論和合成(一個字段)的主鍵,但我從來沒有在25年的數據庫工作看到有人做的DBase或Cobol以外的人。這是史詩般的無知。尖尖的頭髮老闆。

+0

感謝您的輸入! :) – Ascendant

1

嗯,你可以做這樣的事情(假設SQL 2008 R2 +):

create table dbo.keep_the_peace (
    pk as right(replicate('0',10)+convert(varchar(10),pk_generator),10) persisted not null 
, pk_generator int not null identity(1,1) 
, name nvarchar(128) not null 
, constraint pk_keep_the_peace primary key nonclustered (pk) 
, constraint uc_keep_the_peace unique clustered (pk_generator) 
) 
go 

insert dbo.keep_the_peace (name) values ('Hello') 
insert dbo.keep_the_peace (name) values ('World') 

select * from dbo.keep_the_peace 

優點:

  1. pk爲varchar,CTO可以使用LIKE
  2. pk是自動生成的,無需重新插入表格
  3. pk以正確的順序排序,這歸功於零填充。
  4. pk_generator可用於外鍵約束,每個引用可節省6個字節,而CTO仍可加入pk並獲得正確的結果。
  5. keep_the_peace非聚集索引將享受瘦聚集鍵(pk_generator

缺點:

  1. pk + pk_generator使用每行14個字節,比需要10個。
  2. pk_keep_the_peace每行使用14個字節,超過14個字節。(LOL)

編輯

什麼他強烈認爲,我們使用的是像他說,這樣一來,查詢優化器 「從 員工那裏@columnName像@value選擇*」會運行得更好。

  • 沒有這樣的語法:列名不能沒有動態SQL參數化。
  • 沒有這樣的好處:每次列名更改時都會生成新的執行計劃。

如果WHERE子句中的列發生更改,那麼您的查詢將被重新編譯。沒有辦法避免這種情況。列可能有不同的索引。

例如,在id聚集索引,這將作爲執行一個聚集索引查找:

select * from employee where id = 6 

而這將需要昂貴的表掃描:

select * from employee where name like 'somename%' 

把非聚簇索引name,對於相同的查詢,您可以獲得更高效的索引查找+書籤查找(通常)。

INT vs CHAR與它無關。沒有。字符鍵只有較大的佔用空間(一般情況下),佔用空間較大會降低I/O吞吐量。但是這些vanilla查詢的性能將遠遠大於數據類型的索引。

+0

是的我的意思是在MS SQL中使用@表示字符中的存儲過程。無論如何感謝您的幫助。這退出清除了我的想法! – Ascendant

+0

當然,np。要清楚:你不能在T-SQL的列名之前使用'@',它不能在存儲過程或其他任何地方使用。如果允許,它會使用其他語法,如'$ columnName'。 –

相關問題