數 據 庫 使 用 規 則 (收集)

使
術語:
站點(SITE
  公司已建立的或待建立的網站,如:中文站(CHINA),國際站(ALIBABA),華商站(CHINESE)等。
OLPS
  Online process system,在線處理系統,即我們的會員可以瀏覽的網站所連接的數據庫,也是我們所說的前臺。
BOPS
  Back Office process system,後臺處理系統,即我們的網站的發佈系統。
BZO
  Business Object(?),公司網站低層JAVA對象,主要負責與數據庫打交道。
一、 命名約定
1. 是指數據庫、數據庫對象如TABLESEQUENCEPROCEDURECOLUMN等的命名約定;
2. 命名富有意義英文詞彙,除個別通用的(見列表),要避免使用縮寫),多個單詞組成的,中間以下劃線分割;
3. 除數據庫名稱長度爲18個字符,其餘爲130個字符,Database link名稱也不要超過30個字符;
4. 命名只能使用英文字母,數字和下劃線;
5. 避免使用Oracle的保留字如level、關鍵字如type(見列表);
6. 名錶之間相關列名儘量同名;
7. 數據庫的命名:網上數據庫命名爲“OLPS”+表示站點(SITE,以下同)的24個字符,後臺數據庫命名爲“BOPS”+表示站點的24個字符。測試數據庫命名爲“OLPS|BOPS”“TEST”, 開發數據庫命名爲“OLPS|BOPS”+“TEST”,用模式(SCHEMAUSER)的不同來區分不同的站點。
8. INDEX命名:table_name+column_name+index_type(1 byte)+idx,各部分以下劃線(_)分割。多單詞組成的column name,取前幾個單詞首字母,加末單詞組成column_name。如:samplemember_id上的index: sample_mid_idx   newstitle上的unique index:news_titile_uidx
9. SEQUENCE命名:seq_+table_name
二、 註釋說明
1. 本註釋說明主要用於PL/SQL程序及其它SQL文件,其它可作參考;
2. SQLPLUS接受的註釋有三種:
――
 這兒是註釋
/* 這兒是註釋 */
REM
 這兒是註釋
3. 開始註釋,類似JAVAK中的開始註釋,主要列出文件名,編寫日期,版權說明,程序功能以及修改記錄:
REM
REM
 $Header: filename, version, created date,auther
REM
REM Copyright
REM
REM FUNCTION
REM function explanation
REM
REM NOTES
REM
REM MODIFIED
 (yy/mm/dd
REM who when - for what, recently goes first
4. 塊註釋,如表註釋,PROCEDURE註釋等,同JAVA:
/*
* This table is for TrustPass
* mainly store the information
* of TrustPass members
*/
5. 單行註釋,如列註釋:
login_id VARCHAR2(32) NOT NULL, --
會員標識

三、 縮進
低級別語句在高級別語句後的,一般縮進4個空格:
DECLARE
v_MemberId VARCHAR2(32),
BEGIN
SELECT admin_member_id INTO v_MemberId
FROM company
WHERE id = 10;
DBMS_OUTPUT.PUT_LINE(v_MemberId);
END;

同一語句不同部分的縮進,如果爲sub statement,則通常爲2個空格,如果與上一句某部分有密切聯繫的,則縮至與其對齊:
BEGIN
FOR v_TmpRec IN
(SELECT login_id,
gmt_created, -- here indented as column above
satus
FROM member -- sub statement
WHERE site = 'china'
AND country='cn' )
LOOP
NULL;
END LOOP;
END;
四、 斷行
一行最長不能超過80字符
同一語句不同字句之間
逗號以後空格
其他分割符前空格
SELECT
 offer_name
||','
||offer_count as offer_category,
id
FROM category
WHERE super_category_id_1 = 0;
五、 大小寫
屬於ORACLE的關鍵字大小,表名、列名等小寫。
六、 列類型的選擇
CHAR(1)代替布爾值;
應儘量使用VARCHAR2代替CHAR類型;
• VARCHAR(2)
最多4000字符;
• DATE
精確到微秒,而非天;
使用CLOB代替LONGBLOB代替LONG RAW
• ORACLE
只有NUMBER一種數據類型,使用時請給定長度;
七、 主鍵選擇
選擇有意義的,不太長且能唯一標識記錄行的列做主鍵,沒有這種列時,才考慮使用SEQUENCE做主健。
八、 列長度的選擇
應當根據實際需要選擇列長度。有對應web 頁面的,與頁面上對應列長度一致。

對數據的驗證除數據庫端實現外還要儘可能在表現層控制。
九、 使用SQL語句的約定
1. 儘量避免在循環中使用SQL語句。
2. 避免在WHERE字句中對列施以函數:
SELECT
 * 
FROM
 service_promotion
WHERE TO_CHAR(gmt_modified,’yyyy-mm-dd’)
= ‘20001-09-01’;
  而應使用:
SELECT *
FROM service_promotion
WHERE gmt_modified
>= TO_DATE(‘2001-9-01’,’yyyy-mm-dd’)
AND gmt_modified
< TO_DATE(‘2001-9-02’,’yyyy-mm-dd’);

3. 避免使用數據庫的類型自動轉換功能:
SELECT * FROM category
WHERE id = ‘123’; -- id’s type is number
4. 避免無效的連接:
SELECT count(*)
FROM offer a, count_by_email b
WHERE a.email(+) = b.email;
5. 連接(join)時要使用別名:
SELECT a.*,b.offer_count(*)
FROM offer a, count_by_email b
WHERE a.email(+) = b.email;
6.
TABLE META信息:
SELECT *
FROM table_name
WHERE rowid is null (or rownum = 1 or pk = impossible_value);
可考慮使用:
SELECT *
FROM table_name
WHERE 1 = 0 ;



十、 關於ALIBABA表的約定
如果使用ALIBABA BZO,設表至少有如下字段:
site VARCHAR2(32)
gmt_create DATE
gmt_modified DATE
如果從IdBizObject繼承,則還有一個NUMBER型的列,通常是主鍵,並與某一個SEQUENCECF 對應;如果從StrIdBizObject繼承,則還有一個VARCHAR2型的列。
十一、 列值約定
1. 有固定值列表的列,如status, action, site, 其值取小寫;
2. 應儘可能選擇數字來代表固定值列表中的值,相應的列定義爲NUMBER型;
3. CHAR1)表示布爾值的取大寫:“Y”“N”
十二、 關於表重複屬性的定義
不能有多擇一的重複屬性列;

對於能多選的重複屬性列,如果不做查詢列並且重複次數較多,應使用ID_VARRAY代替,如要用作查詢列,重複次數多的,應另建一表,次數少的且列值爲二擇一時,應使用NUMBER類型,加位操作。
十三、 數據修改約定
發現Production環境中數據有誤,需要改正的,應在RA TERMINAL上提交數據更新表單,由數據庫操作員在當日17時前修改完畢。

數據庫更程序更新的結構變動及數據更新,類似處理。

提交SQTT測試需要準備數據或更新結構的,暫時先寫入測試請求中,由SQTT同志MAIL(註明測試請求表單鏈接即可)通過數據庫操作員修改數據庫。待內部網TEAM增加新的表單後,測試請求分開提交。
十四、 數據庫設計流程
在新項目設計階段會議,應有DBA參加。在SCHEMA確定以後方可開始編碼。


縮寫字列表:
payment pymt
my trade activity mta

特殊字列表:
ACCESS DECIMAL INITIAL ON START
ADD NOT INSERT ONLINE SUCCESSFUL
ALL DEFAULT INTEGER OPTION SYNONYM
ALTER DELETE INTERSECT OR SYSDATE
AND DESC INTO ORDER TABLE
ANY DISTINCT IS PCTFREE THEN
AS DROP LEVEL PRIOR TO
ASC ELSE LIKE PRIVILEGES TRIGGER
AUDIT EXCLUSIVE LOCK PUBLIC UID
BETWEEN EXISTS LONG RAW UNION
BY FILE MAXEXTENTS RENAME UNIQUE
FROM FLOAT MINUS RESOURCE UPDATE
CHAR FOR MLSLABEL REVOKE USER
CHECK SHARE MODE ROW VALIDATE
CLUSTER GRANT MODIFY ROWID VALUES
COLUMN GROUP NOAUDIT ROWNUM VARCHAR
COMMENT HAVING NOCOMPRESS ROWS VARCHAR2
COMPRESS IDENTIFIED NOWAIT SELECT VIEW
CONNECT IMMEDIATE NULL SESSION WHENEVER
CREATE IN NUMBER SET WHERE
CURRENT INCREMENT OF SIZE WITH
DATE INDEX OFFLINE SMALLINT

CHAR VARHCAR VARCHAR2 NUMBER DATE LONG
CLOB BLOB BFILE
INTEGER DECIMAL
SUM COUNT GROUPING AVERAGE
TYPE


only
供參考,歡迎大家討論


 

技術 PL/SQL

應遵循的PL/SQL編碼規則

作者:Steven Feuerstein

提高編寫PL/SQL代碼數量及質量的四個簡單易行指導方針

我從1990年就開始編寫PL/SQL代碼。這意味着我已經編寫了幾萬行的軟件代碼,但我確信,其中的絕大多數代碼都非常拙劣,而且難以維護。

幸運地是,我發現找到並遵循編寫出更好代碼的新方法還爲時不晚。就是在去年,我的代碼質量有了顯著改進;這些改進主要是由於制定了一些簡單的規則,並像紀律一樣加以遵守。

本文爲PL/SQL新手及有經驗的開發人員提出了四條建議;遵守其中任何一條,你的代碼質量都會有提高。這四點建議都採納,你可能會驚奇地猛然發現:你竟然是一個非常好的程序員,要遠遠超乎你的想象。

所有工作都獨自完成

我們很少有人是孤立工作的;大多數PL/SQL開發工作是在相對較大的機構中進行的。但我們基本上還是在自己的小隔間裏用自己的設備獨自工作。幾乎沒有PL/SQL開發小組進行正規的代碼複查或系統測試。

我不可能通過這篇文章改變你們開發小組的基本狀態。因此,我仔細地選取出以下幾點建議。實施其中任何一點並不需徵得管理人員同意。不論你的小組是大是小,都不必讓其中的每個人都贊同這些編碼規則。你只需按以下建議來改變你的本人的編碼方式:

1. 嚴格遵循命名約定,好像它們就是你的生命支柱。
2.
戒除編寫SQL的嗜好:編寫的SQL越少越好。
3.
使執行部分短小:告別"意大利麪條式的代碼"
4.
找一位夥伴:非常贊同找個人來監督你的工作。

1. 遵循命名約定

如果你建立並嚴格遵循一套命名約定,特別是對於應用程序組件的,你就可以節省很多時間。

當然,遵循命名約定的想法並沒有什麼新意,你可能已經聽煩了。所以我並不提出什麼宏偉的命名計劃,而是給出一些非常具體而明確的約定,然後證明這些約定會多麼有用。

前幾個月我一直在爲PL/SQL開發人員設計、構建一種新工具。它名爲Swyg(可以在www.swyg.com中找到),可以幫助程序員完成代碼的生成、測試及重用的工作。它具有幾個獨特的組件。我爲每個組件指定了一個由兩個字母組成的縮寫名稱,如下所示:

SF-Swyg的基礎部件
SM-Swyg的元數據
SG-Swyg的生成程序
SL-Swyg的代碼庫
ST-Swyg的單元測試

於是,我便遵循1中的命名約定,同時使用這些縮寫。遵循這些約定有什麼好處呢?一般來講,如果我要求一致的命名規則,我就可以更流暢更高效地編寫代碼。

明確地說,這些約定具有可預測性,意思是說我編寫的SQL程序能生成有用的腳本。例如,通過使用1中的約定,可以生成Swyg中所有基礎包的安裝腳本。執行這些工作的SQL*Plus腳本如清單1所示。這類腳本非常有用,因爲它意味着我不必手動維護安裝腳本。當我向Swyg方案中增加另一個表,並生成一組相關包時,我只要運行我的腳本,更新後的安裝腳本便會跳出來。

2. 戒除編寫SQL的嗜好

編寫的SQL越少越好,這似乎與我們的直覺不太一致。對於PL/SQL開發人員來說,這是一個奇特的建議,因爲PL/SQL的主要優點之一就是可以毫不費力地在代碼中編寫SQL語句。不過,這種簡易性也是這種語言的一個致命的弱點。

可以將純粹的SQL語句直接置於PL/SQL代碼中,而無需JDBCODBC之類的中間層。因此,無論何時何地,PL/SQL開發人員只要需要SQL語句,他們通常就會向其應用程序代碼中嵌入SQL語句。那麼這樣做有什麼問題嗎?

PL/SQL代碼中到處使用SQL語句必然會導致以下後果:

  • 儘管實際表現不同,但同一邏輯語句仍會出現重複,從而導致過多的語法分析,且難於優化應用程序的性能。

  • 暴露商務規則和方案。這直接在SQL語句中包含了執行商務規則的邏輯。這些規則總在變化,所以應用程序的維護成本會急劇增加。

當然,你要編寫的每一個PL/SQL應用程序幾乎都是基於基礎表和視圖的。你需要執行SQL語句。問題不在於是否執行,而是何時執行、如何執行。

如果你對數據結構進行封裝,或者將它們隱藏於一個PL/SQL代碼層(通常是一個代碼包)之後,那麼你的應用程序將會更健壯,而且你還會發現創建和維護變得更易多了。

我們來看一個簡單的例子。 假定我需要編寫一個處理某員工工作的程序。第一件事是獲取該員工的全名,定義爲"姓名逗號(,)姓";然後我可以進行詳細分析。清單2給出了這種情況下我很可能要編寫的這類代碼的一個示例。

一切似乎都是這麼簡單和直接;這些代碼可能會有什麼錯誤呢?實際上真是非常糟糕。最主要的是我暴露了一個商務規則:全名的結構。我可能要花費數小時來對此代碼及其所基於的應用程序進行測試。但就在它剛剛投入使用時,我才知道客戶會不斷地打電話告訴我,實際上,他們的全名應該表示爲"名空格姓"

現在怎麼辦?搜索所有位於引號內的單個逗號?

現實的解決方案是使用隱藏所有細節、只提供一組預定義、預測試及預優化並能完成所有任務的程序包。清單3爲基於封裝代碼重新編寫的process_employee過程。hr_employee_tp包提供了用於定義保存姓名的局部變量的類型;hr_employee_rp包含有基於一種商務規則而返回全名的函數。

將顯示PL/SQL語句灌入SQL代碼很容易,同樣,談論封裝這些語句是如何重要也不費勁。但另一方面,編寫執行封裝任務的代碼卻具有挑戰性;甚至是不現實的。生成這些包或許更有意義。

幾年前,我曾幫助構建這樣一個生成程序。該程序段爲PL/Generator,現在由Quest Software公司擁有,PL/SQL開發社區可以免費使用。你可以從我的網站www.StevenFeuerstein.com/puter/gencentral.htm下載。要知道,其封裝體系結構與我在前面所概括的約定不同。PL/Generator創建了一個單獨的包,它包含了一個表的類型、查詢和變化邏輯的全部內容。

當你不再編寫太多的SQL,而是調用執行SQL的程序時,無論你是生成還是編寫自己的定製封裝,你的應用程序都會受益匪淺。

3. 使執行部分短小

面對現實吧:總是與我們的判斷和最新的一系列新年決議相左,我們必須停止編寫意大利麪條式的代碼:龐大而冗長,人們實際上不可能理解它們,更不用說維護或升級了。怎樣才能避免"意大利麪條"?

實際上,答案很簡單:決不允許執行部分超過5060行。這種大小使你能在一頁紙或一個屏幕上查看該代碼塊的整個邏輯結構,這也意味着你可以真實地領會該程序的意圖,而且完全憑直覺就能理解它。

你可能非常同意上述觀點,但同時又嘲笑我的建議:程序代碼永遠不超過50行。沒錯,你應當嘲笑,因爲這當然是不可能的。毫無疑問,你需要超過50行的可執行代碼;問題是你把這些代碼放在哪,以及你怎樣加以組織。

如果採取以下做法,你的確能夠應對各種複雜的要求,並把代碼限制在50行以內:

  • 將所有的商務規則和離散邏輯塊置於其自已的程序(通常是函數)中,從而在任何可能的時候慎重地重用代碼。

  • 儘量使用在程序的聲明部分定義的局部模塊、過程和函數。

假定我在編制一個呼叫中心應用程序。我需要編寫一個程序,它要滿足下面的要求:

"對於特定部門的每個員工,將其工作量(分派給該員工的呼叫次數)同該部門員工的平均工作量進行比較。如果某員工的工作量低於平均工作量,便將下一待處理呼叫分派給此人,並基於這種情況安排約定。"

我從以前的工作中獲悉:我的朋友Claudia已經編寫了一個分析包,它會返回工作量方面的信息。但是分派待處理呼叫和安排約定都是全新的工作,需求文檔的其餘部分對此進行了詳細說明。

最初我想把這15頁的內容全都看完,但我沒有那樣做。我使用了一種稱爲"逐步求精法""由頂向下設計"的技術,並先編寫了清單4中的代碼來實現該程序。

下面給出了清單4中最關鍵代碼行的解釋;由該程序(緊湊的執行部分)的最後開始,向上進行。這似乎有悖於直覺,但這的確是通讀用逐步求精法編寫的程序的最好方式。

2230行。用一個遊標FOR循環(cursor FOR loop)來對指定部門的所有員工進行迭代處理。在第2425行,利用分析包中的程序判定當前的員工是否工作量不足。在第2728行,調用三個程序:assign_next_open_caseschedule_casenext_appointment。我還不知道怎樣實現這些程序,但我知道它們通過其名稱和參數表表達了需要事先完成的工作。

1019行。爲第2728行中的三個程序創建"stub",也就是佔位程序。注意,它們是局部模塊,在assign_workload中進行定義,且不能從其他任何程序調用。

58行。定義一個遊標,以獲得指定部門的所有員工。現在可以設法編譯此代碼。

對這樣一個小程序成功完成編譯好像是個小勝利,也的確如此。完成正確編譯,然後是簡單測試,然後增加一點代碼,再進行正確編譯,以此類推,諸如此類的小勝利締造出構造精良的程序,而且會非常滿意。

我還可以驗證該分析程序是有效的,並且找出了要分派的任務適當僱員。這些工作全部完成後,我將從三個程序中挑出一個,比如assign_next_open_case,進行下一步或下一級別的精細設計。我要閱讀該任務的文檔,並在assign_next_open_case裏編寫一個簡短的執行部分,它可反映該任務的概況。

很快,我的局部過程有了它自己的局部過程和函數,但在該過程的每一步,我的代碼都很短、可讀、易於測試、可根據需要進行調整。

4. 找一位好夥伴

計算機並不會編程,人才會。

有多少次你彎着腰、駝着背坐在計算機前,因無法找出代碼中的錯誤而感到非常鬱悶?先是幾分鐘過去了,接着又過了幾小時。最後,對自己都厭煩了,感到非常失敗,你把頭伸出你的小隔間並請朋友過來幫你看一看。

通常會有下面三種情況之一出現:

  • 當你的朋友從她的椅子上站起來時,一切都在瞬間變得非常清楚。

  • 你的朋友瞥了一眼屏幕,馬上就指出了問題所在。

  • 你的朋友不負責該系統中你所做的部分,所以你必須說明你的程序在幹什麼。當你逐步講解邏輯時,引起錯誤的問題所在會突然暴露在你面前。

事實就是自己很難調試自己的代碼,因爲你自己對它太投入、太專注了。

下一步

閱讀
Oracle數據庫10g的更多信息
oracle.com/database

Feuerstein的更多文章
otn.oracle.com/oramag/webcolumns/2003


這個問題最好的解決辦法是由開發經理創造這樣一種文化:各種想法是共享的、不懂是可以原諒的並不會受到處罰、定期進行建設性的代碼評審。不幸的是,這些文化上的改變是難以實現的。

與此同時,我建議在幫助改變你所在小組的文化的過程中你應起帶頭作用。找到另一位開發人員,最好比你經驗豐富,並建立一種"夥伴"關係:在出現問題時,他可以充當你的參謀,當然,你也可以充當他的參謀。事前達成共識:不知道所有問題的答案並沒有什麼不對。

然後爲你自己制定一條簡單的規則:不要爲一個錯誤苦思冥想超過半個小時。30分鐘過去後,把你的夥伴叫過來,讓人類心理學爲你服務,而不是跟你作對。

獲得一種新工作方式的四個步驟

本文爲你提供了可以採取的用於改變你的編程體驗四個步驟,而無須投資新的工具或改變整個小組的工作流程。這四步甚至可以不全部遵循,只要遵守一步都會讓你受益。

Steven Feuerstein ([email protected]) PL/SQL語言方面的一位權威人士。Feuerstein撰寫了9本有關PL/SQL (全部由O'Reilly & Associates出版公司出版)的書籍,其中包括《Oracle PL/SQL最佳實踐(Oracle PL/SQL Best Practices)》和《Oracle PL/SQL編程(Oracle PL/SQL Programming)》。他還是Quest Software公司的資深技術顧問。

對象

名稱結構

註釋

生成(DDL)文件

<abbrev>_<entity>

表名,如SM_TASK,用於在普通的Mentat組件中定義的任務。

<abbrev>_<entity>.tab

主鍵列

id

標準是:(幾乎)每個表都包含一個按一個序列生成的id列。對於交叉表等有一些例外。

N/A

用於生成主鍵的序列

<abbrev>_<entity>_seq

用於一個表主鍵的序列名,如SG_SCRIPT_SEQ,它爲Mentat產生腳本表生成一個新主鍵。

<abbrev>_<entity>.seq

查詢封裝包

<abbrev>_<entity>_qp

包含用以在基礎表(如SL_SOURCE_QP)中檢索數據的標準API,它有助於在Mentat可重用庫中查詢各元素的源代碼。

說明:<abbrev>_<entity>_qp.pks
主體:<abbrev>_<entity>_qp.pkb

改變封裝包

<abbrev>_<entity>_cp

包含用以改變(INSERTUPDATEDELETE)某基礎表(如ST_UNITTEST_CP)中的數據的標準API,它使我能夠維護單元測試定義。

說明:<abbrev>_<entity>_cp.pkb
主體:<abbrev>_<entity>_cp.pks

類型封裝包

<abbrev>_<entity>_tp

包含用於指定表(如SG_GEN_RUN_TP)的預定義類型--包括集合、REF CURSORS、記錄。

說明:<abbrev>_<entity>_tp.pks
主體:NA (type definitions do not need a package body)

規則封裝包

<abbrev>_<entity>_rp

包含程序,通常是函數,它隱藏了關係到該實體的商務規則的細節。

說明:<abbrev>_<entity>_rp.pks
主體:<abbrev>_<entity>_rp.pkb

其他物件包

<abbrev>_<entity>_xp

包含特定實體的自定義邏輯。

說明:<abbrev>_<entity>_xp.pks
主體:<abbrev>_<entity>_xp.pkb

 

關鍵字

  • <abbrev>是由兩個字母組成的縮寫。對於Swyg,它可以是SFSMSGSLST

  • <entity>是商務實體名,如TASK用於定義某人要完成任務列表;SCRIPT用於代碼生成模板;等等。

 

 

發佈了27 篇原創文章 · 獲贊 1 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章