來自學習和實操后的總結,有說得不對的,或者遺漏的,大家留言補充。希望這個貼子,能成為活字格老鐵們使用外聯庫的一個指南。PS即使你不打算使用外聯庫,里面的一些方法,也值得看一看!
一、庫表規划
1、系統表:如組織架構、用戶、角色、權限等。活字格內置在sqlite中,無法直連,可通過視圖方式讀取出來
2、詞典表dictionary:輔助填報的列表信息,如行政區域、男女、學歷、崗位、合同類型、商品類別等。其中數據量多、結構比較獨特或需要中台設定的,單獨做表,如行政區域表(記錄多)、商品類別(中台設定)等,其它放在通用詞典表,做一些表設計,我一般是設置類別字段、屬性字段(固定參/可變參)、排序字段、圖片字段、三個字符字段,三個小數字段。
3、業務表business:記錄業務的發生,這是使用最多的表
4、當前表current:存放當前值/累計值或檔案類,如當前庫存、累計銷售、商品檔案等
5、期末表end:存放某個時期的期末結存數,如月末庫存
6、期間表period:存放某個時期內的發生值,如月銷售統計
二、建表
1、表命名:目前我使用的表命令方法:模塊英文標識_表主名使用駝峰法,如hr_employee,hr_employeeFamily
2、視圖命名:模塊英文標識v_視圖的作用
3、函數命名:模塊英文標識p_函數的作用
4、表名/字段長度:雖然mssql可以128個字符,但還是建議在64個以內
5、字段名全部用英文,字段全部用小寫英文字母,字母開頭,不同單詞用_連接,不用復詞,即使是內置的sqlite,也建議用英文名
6、表/字段設計時,盡可能都加注釋,我會把字段注釋全部入到表注釋那里,省時間。如果字段有固定參的,最好也把固定參定上(2020-9-5改)
7、臨時表,使用內置的sqlite表,可以提升效率,特別是進行中間計算或笛卡爾積時,能極大的提升效率,注意,是極大!
8、在活字格內先建表,然后在數據庫IDE中設計表。這樣會在前面幾個字段自動建立ID(默認主鍵)、FGC_CreateDate、FGC_LastModifier、FGC_LastModifyDate、FGC_Creator、FGC_Rowversion、FGC_UpdateHelp字段。主鍵、並發、權限問題一次性解決。PS.自建字段千萬不要去動,另外,外聯表的字段設計不要在活字格里弄,因為數據類型有限。
三、字段
1、mysql里能用char,就不用vchar,mssql也一樣。另外,mssql里,如果有中文就用nchar和nvarchar,純英文和數字,那就用char和varchar
2、vchar不超過5000,如果超過,用text,並獨立出一張表,用主鍵對應
3、tinyint-255,smallint-65535,int-42.9億,bigint-最大,實際使用時再放大幾個零
4、小數類型,如果是金融類的一定要用decimal(18,2),float(7位)和double(15位)自己選擇。(2020-9-5改)
5、是否字段用is_,如果是表現已經狀態,如is_deleted,1表示已刪除
6、數據表雖然有二進制字段,但活字格的圖片和附件都是以字符串形式記錄地址,以防萬一,在mssql里我都直接用nvarchar(max)來
7、表名、字段名、字段類型真得非常重要,在生產環境中,基本上沒有機會可以更改,對有長度的字段類型,還是要留有余量
8、一張表只能有一個timestamp時間戳類型,如果你給活字格修改數據表的權限,活字格會自動幫你建一個,那是用來防止並發臟讀的。重復一次,活字格自動建的幾個字段,不要去改動,包括字段類型也不要去動!
9、SQL數據庫的日期,一般有date、datetime、datetime2三種,活字格的日期對應的是datetime。之前,為了省資源,將日期設為了date,但期間出現的幾次時間字段的數據庫報錯。出現幾次后,發現了規律,就是數據庫連接斷開,重新連的時候,活字格會把date字段識別為文本,這樣就會出現報錯。所以,建議外聯數據庫的日期還是設置為datetime,時間則設置為time(7,0),和活字格的機制保持一致!
四、主鍵/外鍵
1、主鍵最好只用自然主鍵,不要和業務關聯,比如活字格自動新建的ID字段,同時盡量避免用聯合主鍵
2、外鍵使用比較講究,先說邏輯外鍵,就是活字格中設置關聯字段,但不設置聯級約束,就是邏輯外鍵(在活字格里不能設置外聯表的聯級約束,需要在數據庫IDE中設置),邏輯外鍵可以隨意用。但聯級約束外鍵要慎用,因為每次增改刪都會觸發聯級查詢,會影響效率。阿里的開發手冊干脆就直接干掉聯級外鍵了。
3、如果一定要用聯級外鍵,注意以下幾點:(1)引用列並不一定非要主鍵,但必須是唯一列;(2)外鍵列與引用列的數據類型/字符集/校對規則要一致;(3)外鍵列和引用列都必須建索引;(4)外鍵列引用多個列的,列順序要一致;(5)大對象字段不要用做引用列;(6)外鍵命名在庫里要唯一,命名規則fk_本表名_引用表名_on_引用字段,表名的模塊縮寫和結尾標識去掉;(6)如果子表弄了觸發器,外鍵聯級更新是不會觸發的,所以這種情況不要用;(7)不再支持分區表了,所以有計划用分區表的,不要用外鍵;(8)高並發更新表情況下,一定一定要避免使用聯級外鍵
4、雖然阿里不建議用聯級外鍵,但在非常嚴格要求主子表一致性、表結構簡單、並發不高、查詢數據量不高時,可以用一下。其它情況,需要聯級約束的,最好在前端通過設計來實現
5、身份證號、銀行賬號、社保賬號之類敏感的字段,不要做主鍵或外鍵
五、索引
1、索引命名:主鍵索引pk_表名_字段名,表名的模塊縮寫和結尾標識去掉,唯一索引uk_,普通索引idx_。如果你選擇在活字格中建外聯表,會自動建立一個ID的索引(主鍵自動建索引),最好按規則改一下名。注:索引需要在數據表IDE中建,活字格中建不了
2、業務上具有唯一特性的字段,即使是多個字段的組合,如果要建立索引,則必須建成唯一索引
3、索引如果不確定要用,可以先不設置,后期進行sql優化時再使用。一般建在多表聯接用的關聯字段以及查詢頻率較高的條件字段上。
4、vchar索引,如果比較長,需要注意。一般20長度已經能覆蓋90%的查詢判斷, 可以用count(distinct left(列名, 索引長度))和count(*)的來測試決定,設置方式column_name(length)
5、where和orderby有索引字段,且該字段在復合索引中時,將該字段放在復合索引最后
6、建組合索引的時候,區分度最高的在最左邊。如where a=? and b=? ,如果 a 列幾乎接近於唯一值,那么只需要單建a列 索引即可
7、存在非等號和等號混合時,在建索引時,請把等號條件的列前置。如:where c>? and d=? 那么即使 c 的區分度更高,也必須把 d 放在索引的最前列,即索引 idx_d_c
8、不要索引常用的小型表
9、查看select是否使用了索引、使用了哪個索引,可以使用用執行計划(EXPLAIN,在IDE中使用)查詢結果,看key和key_len兩項
10、mssql設置為主鍵和唯一鍵的,會自動建索引,不需要另外建;mysql的唯一鍵,是通過建立唯一性的索引來設置,主鍵也會自動建索引;
六、其它
1、join不要超過3個表,join字段數據類型必須一致。多表關聯查詢時,保證被關聯的字段需要有索引。
2、查詢先快速定位需要獲取的 id 段,然后再關聯,如:SELECT a.* FROM 表 1 a, (select id from 表 1 where 條件 LIMIT 100000,20 ) b where a.id=b.id
3、如果對字符編碼和引擎不熟悉,反正看到UTF8、innodb的字眼,選它就對
4、反范式:字段允許適當冗余,以提高查詢性能,但必須考慮數據一致。冗余字段應遵循:(1)不是頻繁修改的字段;(2)不是 varchar 超長字段,更不能是 text 字段;(3)不是唯一索引的字段。舉個例子就明白:商品類目名稱使用頻率高,字段長度短,名稱基本一不變,可在相關聯的表中冗余存儲類目名稱,避免關聯查詢。看了一個測試,150萬的數據,一個35秒,一個幾秒,驚呆了
5、通常數據庫優化的方向:(1)服務器硬件(三大件);(2)服務器布置環境(比如你用mysql,就一定不能在windows環境里);(3)SQL本身優化;(4)反范式;(5)索引優化。查一下關鍵詞“慢查詢”、“慢sql”、“perl”。
6、阿里開發手冊是禁止使用存儲過程的,認為存儲過程難以調試和擴展,更沒有移植性。但也有人認為可以使用,比如一些常用的關聯表功能組,還是可以封裝。但原則是前后端設計能解決的,就不要用存儲過程,特別是現在有了服務端命令,應該可以盡量避免使用
7、設計視圖要從業務出發,視圖和業務建立一對一的關系,不要因為想讓一個視圖為多個業務服務,而放進不需要的語句、表和字段。視圖不要嵌套視圖,效率會被大大影響,和join一樣,也不要超過3個表。太復雜的,可以考慮走存儲過程,效率會更高。活字格中不能直接建立外聯表的視圖,需要在數據庫IDE中建立,導入時需要選擇主鍵,SQL里視圖是沒有主鍵概念的,但既然它讓你設,你就設一個吧,據說能提高性能。而且,如果你不設,表名旁邊的圖標會顯示為和普通表一樣,而且不是視圖特有的圖標,完美主義者的我,是不能容忍這種事情的
8、關於外聯表選mssql還是mysql,如果活字格服務端和數據庫在同一個服務器,還是自己安裝數據庫,就用mssql,大多數人推薦2008R2和2012,我已經升級到2012。這種情況選mssql的原因,一是阿里雲和騰訊雲親測都可以安裝使用,盜不盜版,如果不是做公有雲布置,估計也沒啥問題,二是windows環境還是用mssql,而且活字格是.net的,屬於一家人;三是你自己下載安裝的mysql和騰訊雲提供給你的mysql是不一樣的,自己安裝的話,最好不選mysql。如果是使用阿里雲或騰訊雲的雲數據庫,那就選 mysql,一是更便宜,二是他們都做了優化,也有很多優化工具可以使用,比如前面的慢sql,不比mssql差。
9、數據庫IDE,因為計划只用sqlserver,所以改用原生的IDE,SQLserver同一個安裝包,安裝時只選IDE就可以,可網上搜教程(2020-9-5改)
10、最后說說,我對選內置數據庫還是外聯數據庫的看法。既然寫了這么多外聯數據庫的東西,自然我的選擇是外聯數據庫了。選什么不重要,重要的是為什么選?所以簡單說一下原因:(1)百度sqlite,出現最多的關鍵詞,是輕型、嵌入、桌面、不需要配置安裝,然后sqlite支持高並發的讀,但不支持高並發的寫,等等,我們是要用活字格來做企業業務應用的,而且是web應用,你會覺得sqlite的特點和需求吻合嗎?;(2)上面說了很多數據庫優化的東西,無論是mssql還是mysql,都有非常多的優化教程、方法和工具,阿里雲和騰訊雲也都有提供專門的數據庫優化工作和方案,我認為在數據量到百萬甚至是幾十萬級的時候,性能上的表現一定會突出出來,而sqlite的優化空間太小;(3)接觸到外聯數據庫,我才打開了一個新的窗口,才能寫以上的東西。我相信很多用內置庫的老鐵們,表名字段名還是用中文吧,你不用外聯庫,你就根本不會關注到這些東西;(4)外聯mysql和mssql都可以直聯,這樣可以方便的相互竄門,而sqlite雖然是活字格內置的,但卻不能直連。
PS:雖然我選擇了外聯數據庫,但我仍然會經常用到內置庫,比如前面說的,在一些臨時表和中間表的使用上,我基本上都是用sqlite,很多情況下,執行效率比外聯表高很多,這樣你的外聯庫看上去也清爽些。所以,活字格的內置庫用sqlite我覺得挺好的,內置和外聯,相互補充。另外,新接觸低代碼系統的老鐵們,進入門檻也大大降低了~~~
11、看了幾篇關於mysql和mssql安全性能的比較,以及雲開發中雲函數可以外接mysql,再加上兩者雲數據庫相關兩三倍的價格,心血來潮,花了一天時間搗鼓mysql,結果踩了坑。測試的環境,包括(1)使用騰訊雲數據庫mysql,與安裝活字格的騰訊雲服務器在一個私有網絡內連結;(2)直接在安裝活字格安裝騰訊雲服務器上自建mysql。原來環境是在騰訊雲服務器中自建mssql。結果兩個mysql環境效率,都比mssql環境,低了2倍左右。這個結果,不能說mysql的執行效率比mssql低,但至少可以下結論:活字格中,使用mssql比使用mysql的效率更高。所以使用外聯數據庫,還是好好把mssql用好。附兩個測試點:(1)頁面表格500行數據,使用提交表格命令,mssql>2-3分鍾左右,mysql>6-8分鍾
(2)頁面兩個表格,根據單元格值變化執行查詢命令,mssql>1秒左右,mysql>3-5秒
12、另外,也總結一下使用mysql的注意事項:
(1)字符集選擇utf8或utf8mb4,騰訊雲官方是建議直接用uft8mb4,能支持表情字符,因為很多人的微信名會用表情字符。這兩種字符集,排序規則都用general_ci。這個和mssql不一樣,在mssql里,沒有字符集的選擇,是通過選擇排序規則來選擇的,選Chinese_PRC_CI_AS
(2)是否,用tinyint(1)
(3)補充一下幾個小數float、double和decimal的應用,三個精度依次提升,但效率也依次降低,和前文說的有不一樣的地方。A、金融相關的,一定用decimal,大小一般設置為(18,2),不用decimal,會遇到浮點不等情況;B、float效率最快,但只有7個有效位,比如你設置為(7,4)的話,最多只能表示***.****, 一些參數型、百分率的字段我會用到;C、double翻一倍,15個有效位
(4)mysql的數據類型更少,比如沒有nvarchar(max)、varchar(max)這樣的,所以在mysql里,長文本要用text
(5)活字格的圖片和附件轉到mysql,是用varchar(500),多附件這種,可能會遇到字符長度不夠的情況,如果預計不夠,會要改一下。不過至今我還是沒搞清楚,究竟varchar最長可以放多少個字符,找資料,有說255的
(5)mysql里沒有設置唯一鍵的地方,是通過建唯一索引來設置唯一鍵,索引類型一般選unique或normal(index),索引方法一般BTREE。主鍵會自動建一個索引