[20190930]關於資料結構設計問題.txt

lfree發表於2019-10-04

[20190930]關於資料結構設計問題.txt

--//快放假,沒有什麼事情,我整理電子郵箱,發現N年前乙方一封電子郵件,現在讀起來真的苦笑不得。
--//想起以前剛開始學習oracle時,一位開發給我寫的一段話,不知者無畏,現在看來這句號應該送還給對方。

1.出於安全考慮我不貼出具體內容,我大概描述我提的建議:

--//一個表有一個欄位result,裡面記錄一些從儀器上讀取的記錄。格式如下:
201310230915:111,222,333,444....,888

--//很明顯冒號前面是一個時間,僅僅沒有秒罷了。實際上嚴格講這個設計違反資料結構設計的。因為把2個屬性的內容放入一個欄位。
--//其實我並不關心這些,我僅僅做優化工作,因為經常執行這樣類似的查詢條件:

select * from x where patient_id='123' and result like '201310230915%';

--//語句很簡單,通過patient_id='123'條件返回記錄很多,導致邏輯讀有點高。我不大可能建立複合索引,因為result欄位佔用空間很
--//大。我僅僅提出建議這樣設計不合理,如果分開2個欄位更好,這樣查詢語句可以寫成如下:

select * from x where patient_id='123' and result_time = to_date('201310230915','yyyymmddhh24mi');

--//實際上可能對方理解我要求改資料結構,我個人從來不會提那些"不現實"的改動,我僅僅要求把這條語句改寫如下:

select * from x where patient_id='123' and substr(result,1,12) = '201310230915';

--//看看對方的回覆:
--//大概意思是這樣設計可以節省儲存空間,按照他的理解字串儲存的'201310230915'(少了秒)比採用日期格式儲存的時間更節省空間。
--//真的是"不知者無畏",很明顯對方並不知道和了解oracle日期儲存格式以及佔用空間大小。oracle的日期儲存僅僅佔用7個字元。
--//而那一串表示時間的字串佔用12個字元,而且取日期不要秒很簡單,僅僅使用trunc函式就可以實現。

SCOTT@test01p> select sysdate,trunc(sysdate,'mi') ,dump(sysdate,16) c40, dump(hiredate,16) c40,hiredate from emp where rownum=1;
SYSDATE             TRUNC(SYSDATE,'MI') C40                                C40                            HIREDATE
------------------- ------------------- ---------------------------------- ------------------------------ -------------------
2019-09-30 20:31:50 2019-09-30 20:31:00 Typ=13 Len=8: e3,7,9,1e,14,1f,32,0 Typ=12 Len=7: 77,b4,c,11,1,1,1 1980-12-17 00:00:00

SCOTT@test01p> select sysdate,dump(sysdate,16) c40, dump(hiredate,16) c40,hiredate from emp where rownum=1;
SYSDATE             C40                                      C40                                      HIREDATE
------------------- ---------------------------------------- ---------------------------------------- -------------------
2019-09-30 20:32:49 Typ=13 Len=8: e3,7,9,1e,14,20,31,0       Typ=12 Len=7: 77,b4,c,11,1,1,1           1980-12-17 00:00:00
--//注:直接取sysdate的型別與儲存在資料庫的日期型別有一點點不同.

--//我依稀記得去年我還看了這個應用專案,語句還是使用前面的like。我一直有一種感覺,開發很不願意改動"執行"正確的程式碼,實際
--//上執行錯誤的程式碼也不會改動,而對於使用具體使用者提的建議卻非常認真及時對待(至少比對我們要好一些),實際上具體使用者一些建
--//議在我看來完全沒有必要實現,可能看問題的角度真的不同^_^。

--//包括內部一些開發專案也是一樣,我看一下N年前我提的建議到現在都沒有改,甚至執行錯誤的語句。

2.再來看看另外的專案:

--//我們生產系統,表中存在大量表示狀態的欄位status,flag欄位,開發全部使用number型別,實際上又是開發不瞭解oracle number類
--//型的儲存僅僅0佔用1個位元組。其他數字至少佔用2個位元組。

--//而且該欄位經常改動,往往是0修改其他值,這樣就不能實現就地修改,要改寫行目錄的偏移量,而且這些欄位可能還會出現在各種
--//索引中的一部分。還有一些開發使用-1表示某些狀態,很明顯不瞭解-1在oracle儲存佔用3個位元組。我曾經開玩笑講使用-1,不如使用
--//100,1000,1000呢?

SCOTT@test01p> select dump(-1,16),dump(1000,16) from dual;
DUMP(-1,16)           DUMP(1000,16)
--------------------- -----------------
Typ=2 Len=3: 3e,64,66 Typ=2 Len=2: c2,b

--//繼續看看連結,不再貼出:
[20180309]不好的資料結構設計.txt =>http://blog.itpub.net/267265/viewspace-2151657/
[20180312]不好的資料結構設計2.txt=>http://blog.itpub.net/267265/viewspace-2151736/

--//真心無法體會這樣設計帶來的好處!!

3.繼續:

--//再談自己遇到的一個ms sqlserver資料庫,N前遇到的問題,同事要求協助解決問題。
--//當我連線資料庫才發現開發定義資料欄位那個亂啊,簡單講比如patiend_id欄位:有一些定義型別是nvarchar2.一些表定義
--//為varchar2,其他欄位就不在提了,一個表裡面一部分用nvarchar2,另外一部分使用varchar2,簡直亂的一塌糊塗。
--//我當時想這樣的專案怎麼能在許多醫院上執行,沒有良好的硬體根本撐不住。

--//我當時只能找來實施人員講明具體的情況,不過講完我就不在理會這些問題,順便說一下我個人並不主張nvarchar2型別,其實目前
--//僅僅姓名欄位使用narchar2有點意義。不過過了幾天,對方跟我講他花了一個晚上時間,修改很大部分欄位比如patient_id全部統一
--//使用nvarchar2,還跟我講感覺現在系統快了許多...

4.總結:

--//不小心有寫了一大堆。我在這個行業見到許多奇葩事情,有時候真心很無奈..........

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/267265/viewspace-2658885/,如需轉載,請註明出處,否則將追究法律責任。

相關文章