天天看點

解析大型.NET ERP系統 20條資料庫設計規範

資料庫設計規範是個技術含量相對低的話題,隻需要對标準和規範的堅持即可做到。當系統越來越龐大,嚴格控制資料庫的設計人員,并且有一份規範書供執行參考。在程式架構中,也有一份強制性的約定,當不遵守規範時報錯誤。

解析大型.NET ERP系統 20條資料庫設計規範

以下20個條款是我從一個超過1000個資料庫表的大型erp系統中提煉出來的設計約定,供參考。

1  所有的表的第一個字段是記錄編号recnum,用于資料維護

[recnum] [decimal] (8, 0) not null identity(1, 1)

在進行資料維護的時候,我們可以直接這樣寫:

update company set code='flex'  where recnum=23

 2 每個表增加4個必備字段,用于記錄該筆資料的建立時間,建立人,最後修改人,最後修改時間

[createddate] [datetime] null,

[createdby] [nvarchar] (10) collate sql_latin1_general_cp1_ci_as null,

[reviseddate] [datetime] null,

[revisedby] [nvarchar] (10) collate sql_latin1_general_cp1_ci_as null

架構程式中會強制讀取這幾個字段,預設寫入值。

 3  主從表的主外鍵設計

主表用參考編号refno作為主鍵,從表用refno,entryno作為主鍵。refno是字元串類型,可用于單據編碼功能中自動填寫單據流水号,從表的entryno是行号,lineno是sql server 的關鍵字,是以用entryno作為行号。

如果是三層表,則第三層表的主鍵依次是refno,entryno,detailentryno,第三個主鍵用于自動增長行号。

4 設計單據狀态字段

字段

含義

posted

過帳,已确認

closed

已完成

cancelled

已取消

approved

已批核

issued

已發料

finished

suspended

5 字段含義相近,把相同的單詞調成字首。

比如工作單中的成本核算,人工成本,機器成本,能源成本,用英文表示為laborcost,machinecost,energycost

但是為了友善規組,我們把cost調到字段的前面,于是上面三個字段命名為costlabor,costmachine,costenergy。

可讀性後者要比前者好一點,visual studio或sql prompt智能感覺也可幫助提高字段輸入的準确率。

6 單據引用鍵命名 sourcerefno  sourceentryno

銷售送貨shipment會引用到是送哪張銷售單據的,可以添加如下引用鍵sourcerefno,sourceentryno,表示送貨單引用的銷售單的參考編号和行号。source開頭的字段一般用于單據引用關聯。

7 資料字典鍵設計

比如員工主檔界面的員工性别gender,我的方法是在源代碼中用枚舉定義。性别枚舉定義如下:

public enum gender

{

        [stringvalue("m")] [displaytext("male")] male, [stringvalue("f")] [displaytext("female")]

        female

}

在代碼中調用枚舉的通用方法,讀取枚舉的stringvalue寫入到資料庫中,讀取枚舉的displaytext顯示在界面中。

經過這一層設計,資料庫中有關字典方面的設計就規範起來了,避免了資料字典的項的增減給系統帶來的問題。

8 數值類型字段長度設計

price/qty 數量/單價  6個小數位   nnnnnnnnnn.nnnnnn 格式 (10.6)

amount 金額   2個小數位          nnnnnnnnnnnn.nn 格式(12.2)

total amt 總金額 2個小數位       nnnnnnnnnnnnnn.nn 格式(14.2)

參考編号預設16個字元長度,不夠用的情況下增加到30個字元,再不夠用增加到60個字元。這樣可以保證每張單據的第一個參考編号輸入控件看起來都是一樣長度。

除非特别需求,一般而言,界面中控件的長度取自映射的資料庫中字段的定義長度。

9 每個單據表頭和明細各增加10個自定義字段,基礎資料表增加20個自定義字段

參考供應商主檔的自定義字段,自定義字段的名稱統一用userdefinedfield。

alter table vendor add  column [user_defined_field_1] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_2] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_3] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_4] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_5] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_6] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_7] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_8] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_9] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_10] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_11] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_12] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_13] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_14] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_15] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_16] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_17] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_18] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_19] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

alter table vendor add  column [user_defined_field_20] nvarchar(100) collate sql_latin1_general_cp1_ci_as null

10 多貨币(本位币)轉換字段的設計

金額或單價預設是以日記帳中的貨币為記錄,當預設貨币與本位币不同時需要同時記錄下本位币的值。

銷售單銷售金額 salesamount或salesamt,本位币字段定義為salesamountlocal或salesamtlocal

通常是在原來的字段後面加local表示本位币的值。

11 各種日期字段的設計

字段名稱

trandate

日期帳日期 tran是transaction的簡寫

posteddate

過帳日期

closeddate

完成日期

invoicedate

開發票日期

duedate

截止日期

scheduledate

計劃日期,這個字段用在不同的單據含義不同。比如銷售單是指送貨日期,采購單是指收貨日期。

orderdate

訂單日期

paydate

付款日期

createddate

建立日期

reviseddate

修改日期

settledate

issuedate

發出日期

receiptdate

收貨日期

expiredate

過期時間

12 财務有關的單據包含三個标準字段

fiscalyear 财年,periodno 會計期間,period 前面二個的組合。以國外的财年為例子,fiscalyear是2015,periodno是4,period是2015/04。

歐美會計期間是從每年的4月份開始,需要注意的是會計期間與時間沒有必然的聯系,看到會計期間是2015/04,不一定是表示2015的4月份,它隻是說這是2015财年的第四期,具體在哪個時間段需要看會計期間定義。

13 單據自動生成 directentry

有些單據是由其它單據生成過來的,邏輯上應該不支援編輯。比如銷售送貨shipment單會産生出倉單,出倉單應該不支援編輯,隻能做過帳扣減庫存

操作。這時需要directentry标準字段來表示。當手工建立一張出倉單時,将directentry設為true,表示可編輯單據中的字段值,當由

其它單據傳遞産生過來産生的出倉單,将directentry設為false,表示不能編輯此單據。這種情況還發生在業務單據産生記帳憑證

(voucher)的功能中,如果可以修改由原始單據傳遞過來的數量金額等字段,則會導緻與源單不比對,給系統對帳産生困擾。

14 百分比值字段的設計

percentage百分比值,用于折扣率,損耗率等相關比率設定的地方。推薦用數值類型表示,用腳本表示是

[scraprate] [decimal] (5, 2) null

預留兩位小數,整數部分支援1-999三位數。常常是整數部分2位就可以,用3位也是為了支援一些特殊行業(物料損耗率超過100)的要求。

15 日志表記錄編号logno字段設計

logno字段的設計有些巧妙,以出倉單為例子,一張出倉單有5行物料明細,每一行物料出倉都會扣減庫存,再寫物料進出日記帳,因為這五行物料出倉

來自同一個出倉單,于是将這五行物料的日記帳中的logno都設為同一個值。于在查詢資料時,以這個字段分組即可看到哪些物料是在同一個時間點上出倉的,

對快速查詢有很重要的作用。

16 基礎資料表增加名稱,名稱長寫,代用名稱三個字段

比如供應商vendor表,給它加以下三個字段:

description 供應商名稱,比如微軟公司。

extdescription 供應商名稱長寫,比如電氣行業的南網的全名是南方國家電網有限公司。

altdescription 供應商名稱替代名稱,用在報表或是其它單據引用中。比如采購單中的供應商是用微軟,還是用代用名稱microsoft,由參數(是否用代用名稱)控制。

17 檔案類表增加md5 hash字段

比如産品資料管理系統要讀取圖紙,單據功能中增加的附件檔案,這類涉及檔案讀寫引用的地方,考慮存放檔案的md5哈希值。檔案的md5相當于檔案的

唯一識别身份,在網上下載下傳檔案時,網站常常會放出檔案的md5值,以友善對比核對。當下載下傳到本機的檔案的md5值與網站上給出的值不一緻時,有可能這個文

件被第三方程式修改過,不可信任。

18 資料表的主鍵用字元串而不是數字

比如銷售單中的貨币字段,是存放貨币表的貨币字元串值rmb/hkd/usd,還是存放貨币表的數字鍵,1/2/3。

存放前者對于報表制作相對容易,但是修改起來相對麻煩。存放後者對修改資料容易,但對報表類或查詢類操作都需要增加一個左右連接配接來看數字代表的貨币。金蝶使用的是後者,它的bos系統也不允許資料表之間有直接的關聯,而是間接通過id值來關聯表。

在我看到的系統中,隻有一個會計期間功能(财年fiscal year)用到數字值作主鍵,其餘的單據全部是字元串做主鍵。

19 使用約定俗成的簡寫

子產品module 簡寫

簡寫

全名

sl

sales 銷售

pu

purchasing 采購

ic

inventory 倉庫

ar

account receivable 應收

ap

account payable 應付

gl

general ledger 總帳

pr

production 生産

名稱name 簡寫

uom

unit of measure 機關

ccy

currency 貨币

amt

amount  金額

qty

quantity 數量

qty per

quantity per 用量

std output

standard output 标準産量

eta

estimated time of arrival 預定到達時間

etd

estimated time of departure  預定出發時間

cod

cash on delivery 貨到付款

so

sales order 銷售單

po

purchase order 采購單

20  庫存單據數量狀态

qty on hand 在手量

qty available 可用量

qty on inspect 在驗數量

qty on commited 送出數量

qty reserved 預留數量

以上每個字段都有标準和行業約定的含義,不可随意修改取數方法。

作者:james li

來源:51cto