使用主鍵(integer)自動產生,是好是壞? |
答題得分者是:danny
|
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
小弟在實作三層,SA覺得開自動編號對SQL Server效能及空間比較節省
但我Client在新增一筆資料時,自動編號欄位無法帶到前端來, 於是搜尋一下網路資料,發現大陸網友發表一篇 http://www.wangwa.com/info/2006-07/7.htm 講三層架構裡,Sql自動編號欄位不適合用 請問有無前輩開發三層的,主鍵是否有用到Integer自動編號成功過? 特別是那種MasterDetail單據.... 謝謝指導 |
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
他不是指出重點了嗎 ?
Master/Detail 因為 Detail 的 Key 必須與 Master 一樣, 而 "自動編號欄位" 必須要 post 後才知道, 那 Detail 在輸入時必無法得知(除非Master 先 post) 不過 Client 端如果只是輸入資料, 在 AP Server 那層也是可以使用的, 就看你認為維護會不會很麻煩來決定是否採用. 台灣統xERP,大陸速xERP,都是用的sql server .都不用identity字段.他們還是用整數做Primary key,但不是identity.這種安排的一個重要原因是主從表的同步問題.因為identity的值做主鍵必須等存盤成功後才知道到底是多少.而從表保存時就需要知道主表的primary key.我在第六部分說的」斷開主從關係」可能也與此相關.在微軟的體系中,他使用identity字段做主鍵.但他用的是嵌套的存儲過程來完成的.如果純面向對像開發來說,這個思路是好的,但對於我們borland族以dataset為中心的開發者來說.就不好用了.微軟例子可以見Duwamish.網上書店..我個人覺得基本表的主鍵可以用identity,主從表的主表是不能用的,從表其實也是可以用identity做主鍵的. ===================引 用 pedro756901 文 章=================== 小弟在實作三層,SA覺得開自動編號對SQL Server效能及空間比較節省 但我Client在新增一筆資料時,自動編號欄位無法帶到前端來, 於是搜尋一下網路資料,發現大陸網友發表一篇 http://www.wangwa.com/info/2006-07/7.htm 講三層架構裡,Sql自動編號欄位不適合用 請問有無前輩開發三層的,主鍵是否有用到Integer自動編號成功過? 特別是那種MasterDetail單據.... 謝謝指導
------
將問題盡快結案也是一種禮貌! |
dyming
初階會員 發表:0 回覆:11 積分:32 註冊:2003-04-21 發送簡訊給我 |
|
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
謝謝danny版主還有dyming回應
如原作者所述問題點 dyming兄您講的這種,存完檔需要再下一次Query,前端才知道剛剛所存的單據號碼, 不知道實作起來容不容易,還有效能如何? 我有想過把identity取消,直接用select max(bilno) from xxxx,取得最大單號,再加一方式 不過用於多Client端會搶號及Server--->Client一來一往耗時 只是好奇為什麼Integer欄位,普遍都不使用? 一定有其它刺手因素在吧? ===================引 用 dyming 文 章=================== identity 確實要存檔後才會產生, 所以主檔新增時先將此欄位預給0, 明細新增時當然也給0, 就解決了主從連結問題. 存檔時當然此欄位不可寫回 (用 TUpdateSQL 避掉此欄位), 主檔先 ApplyUpdates, 於是 identity 欄位就可從主檔 select 出來, 再將此值異動明細欄位, 明細存檔就解決了. |
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
也沒有到 "Integer欄位,普遍都不使用" 吧 ? 這要看你設計的作法而定, 其實我就是使用 Integer.
取單號可以透過特定的 function 確保取得的單號是維一的, Detail 在 Insert 時直接抓 Master 的 Integer 你也可以使用 dyming兄的方式, 先填某一個值(如: 0)給Detail, 等到 AP Server 真的取得 identity 再寫入取得的值. identity 的優點是單號一定會是正確的(唯一的, 給Database處理掉), 而用 Integer 還要自己處理, 當然可以自己加上自訂的單號邏輯(彈性). ===================引 用 pedro756901 文 章=================== 謝謝danny版主還有dyming回應 如原作者所述問題點 dyming兄您講的這種,存完檔需要再下一次Query,前端才知道剛剛所存的單據號碼, 不知道實作起來容不容易,還有效能如何? 我有想過把identity取消,直接用select max(bilno) from xxxx,取得最大單號,再加一方式 不過用於多Client端會搶號及Server--->Client一來一往耗時 只是好奇為什麼Integer欄位,普遍都不使用? 一定有其它刺手因素在吧? ===================引 用 dyming 文 章=================== identity 確實要存檔後才會產生, 所以主檔新增時先將此欄位預給0, 明細新增時當然也給0, 就解決了主從連結問題. 存檔時當然此欄位不可寫回 (用 TUpdateSQL 避掉此欄位), 主檔先 ApplyUpdates, 於是 identity 欄位就可從主檔 select 出來, 再將此值異動明細欄位, 明細存檔就解決了.
------
將問題盡快結案也是一種禮貌! |
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
請問danny版主
如何維護每個Client端只取一個不重覆的單號? 單號如何方便查詢? 如果我用varchar單號欄位 例如960803xxxxxx3,我可輸入960803查96年8月3號所有單據(Like '960803%') 用整數就得加開一個Varchar日期欄位 維護時sql語法用Integer方便麼? 例如我要統計960801到960831未出貨的情況? ===================引 用 danny 文 章=================== 也沒有到 "Integer欄位,普遍都不使用" 吧 ? 這要看你設計的作法而定, 其實我就是使用 Integer. 取單號可以透過特定的 function 確保取得的單號是維一的, Detail 在 Insert? 時直接抓 Master 的 Integer 你也可以使用 dyming兄的方式, 先填某一個值(如: 0)給Detail, 等到 AP Server 真的取得 identity 再寫入取得的值. identity 的優點是單號一定會是正確的(唯一的, 給Database處理掉), 而用 Integer 還要自己處理, 當然可以自己加上自訂的單號邏輯(彈性). |
VICSYS
初階會員 發表:21 回覆:64 積分:32 註冊:2002-10-10 發送簡訊給我 |
對不起! 插花一下
單據自動編號, 不是本來就應該這樣做嗎? 1.用 ClientDataSet 元件, 採用 DataSetField 的方式連接 2.DataSetProvider 加入 poPropogateChanges 3.在 DataSetProvider 的 BeforeUpdateRecord 取得自動編號 ex. if (SourceDS = MasterDataSet) and ( UpdateKind=ukInsert ) then begin SELECT MAX(NO) MAXNO FROM SOMETABE WHERE DATE LIKE '960803%' DeltaDS.FieldByName('BILLNO').NewValue:= MAXNO 1 end; 這時如果使用者只輸入1筆主檔, 並輸入了明細資料, 然後存檔, 這時編號會回傳至 Client 端! 明細的單號也會正確地異動! 如果您是在 Client 用 MasterSource 方式來連接 M/D 就做不到! 只能用 DataSetField 的方式 1.您還必須解決如果使用者 同時輸入多筆主檔, 之後才一起存檔的情況, 這時會在在Client端造成 主鍵重覆(或者是空白)的問題, 但這個問題很好解決, 只要給一個假的唯一的序號即可, 反正 ApplyUpdate 後, 單號會重新取得! 2.DataSetField 的連接方式, 會把該主檔的明細全部讀入! 如果明細資料一多的話, 這會造成問題, 這時個只好改寫 ClientDataSet 的元件! 標題是:使用主鍵(integer)自動產生,是好是壞? 所以我想真正的問題應該是 Insert 之後, 回傳的問題! 而且是當主鍵 不是用 Delphi 去計算得知主鍵! Max(NO) 1, 會知道 Max(NO) 1 的結果 自動欄位, 去取得資料庫的最大編號 1, 就是存入資料庫的真實值嗎? 如果是, 那麼沒有問題! 如果不是呢? 像 Oracle 的 ROWID, 只有存入資料庫後 才會得知, 那麼只好改寫 DataSetProvider 的元件, 只好把 Insert 部份的用自行開發程式來解決回傳的問題! 結論是, 我不用"使用主鍵(integer)自動產生", ROWID 的問題就很大了, 還來一個自動產生的主鍵? |
pedro
尊榮會員 發表:152 回覆:1187 積分:892 註冊:2002-06-12 發送簡訊給我 |
|
danny
版主 發表:100 回覆:522 積分:595 註冊:2002-03-11 發送簡訊給我 |
這要用 database 的 Transaction 來作, 發生 error 就是有人在更新(retry), 沒有 error 就流水號加一, 再更新回 Table
以上作法亦適用於varchar單號欄位, 當然單號的 format 你要自定(你說的 xxxxxx3就是流水號) 還有一種作法也可以使用, 在 APP Server 那層用一個 Integer 變數紀錄流水號, Client 來要單號就將此 Integer 變數流水號加一(排除你的設計不會同時取單號的可能) ===================引 用 pedro756901 文 章=================== 請問danny版主 如何維護每個Client端只取一個不重覆的單號? 單號如何方便查詢? 如果我用varchar單號欄位 例如960803xxxxxx3,我可輸入960803查96年8月3號所有單據(Like '960803%') 用整數就得加開一個Varchar日期欄位 維護時sql語法用Integer方便麼? 例如我要統計960801到960831未出貨的情況?
------
將問題盡快結案也是一種禮貌! |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |