備注學院

          LuLu

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            5 隨筆 :: 50 文章 :: 16 評論 :: 0 Trackbacks
          本文將學習幾個基本的數據庫概念,包括模式、表、列數據類型以及結構化查詢語言(SQL)的簡單介紹。這篇文章 —— 側重于數據庫開發人員的角色 —— 介紹可以用來在 Apache Derby 數據庫中保存數據的基本數據類型,然后用它們在 Apache Derby 中創建一個帶有兩個表的簡單模式,供一個虛擬的商店使用。要查看數據庫的模式內容,可以使用 Apache Derby 的工具 —— dblook,導出數據庫的內容。文章結束時簡單討論了如何刪除表。

          關系數據庫系統基礎

          在開發數據庫應用程序之前,需要理解它的基本概念。這一節介紹在 Apache Derby 中可以使用的數據類型,以及對設計和創建有用的 Derby 數據庫應用程序的能力有影響的規則。

          關系數據庫容納數據。數據可以是不同類型的,例如數值型、字符型或日期型。在數據庫中,數據被組織到叫做 的邏輯單元中。表就像工作簿一樣,因為它包含數據行。每行由許多列組成。列容納特定數據類型的數據,例如整型值或字符串。在多數情況下,一個數據庫有多個表。為了將表關聯在一起,數據庫設計師利用表之間的自然(或人為)鏈接。在工作簿中,可以通過單元格的值鏈接不同工作簿中的行。同樣的概念在關系數據庫中也存在,用來進行鏈接的列叫做鍵列(key column)

          為了讓表或列的用途更容易理解,應當選擇合適的名稱。對于不同的數據庫,命名約定可能不同。對于 Apache Derby 數據庫系統,名稱應當:

          • 不區分大小。
          • 最長 128 個字符。
          • 必須以字母開頭。
          • 必須只包含 Unicode 字母、下劃線和 Unicode 數字。

          通過把名稱放在雙引號中,可以避開 這些規則,使用雙引號允許名稱區分大小寫以及包含附加字符(包括空格)。但是,這么做通常是不好的做法:它要求名稱總被括在雙引號中,很容易把維護代碼的其他人弄糊涂。

          Derby 風格
          這個 文章系列 遵守特定的風格:所有 SQL 命令都用大寫,項目名稱采用 camelCase 方式,在 camelCase 風格中,單詞被連在一起,第一個單詞之后的每個單詞的第一個字母大寫,例如 aLongIdentifier。把這兩種風格組合在一起,這些文章寫 SQL 命令時的風格是這樣:SELECT aLongIdentifier FROM bigdog.dataTable ;.

          關聯的表通常組織在一起,形成一個模式(schema)。可以把模式當成特定數據庫中所有相關結構定義的容器。在指定模式中,表的名稱必須惟一。所以,通過使用模式,可以在不同模式的范圍內擁有名稱相同的對象(例如表)。在使用 Apache Derby 數據庫時,表總在模式中。如果沒有顯式地指定模式,Derby 就會隱式地使用內置的 apps 模式。叫做 sys 的第二個內置模式用來隔離系統表。

          可以用模式名對名稱進行限定(qualify)。要做這件事,可以在模式名后加圓點,然后加表名。例如,bigdog.products 表示 bigdog 模式中的 products 表。沒有相應的模式名,表名就被認為是未限定的(unqualified),例如 products。當模式名和表名都完全指定的時候,就像 bigdog.products,名稱被稱為完全限定的(fully qualified)

          從抽象意義上來說,這些數據庫概念看起來可能讓人混淆。但在實踐上,它們相當簡單。例如,假設有一個商店,叫做 Bigdog's Surf Shop,這家店銷售各種商品,例如太陽鏡、襯衫等等。如果想贏利,就必須管理庫存,以便可以容易地訂購額外的商品或改變供應商,從而把開支控制在最小。跟蹤這些信息的一個簡單方法,就是用表格式編寫條目,如 圖 1 所示。


          圖 1. Bigdog's Surf Shop 的示例模式
          Bigdog's Surf Shop 的示例模式,顯示了一個 Products 表和一個 Vendors 表

          從這個簡單的可視設計中,可以容易地把業務邏輯直接映射到數據庫表。有兩個表:Products 和 Vendors,它們自然地通過商品名稱鏈接在一起。列的數據類型很容易確定。這篇文章其余的部分將側重于在 Derby 數據庫中創建 Bigdog's Surf Shop 的示例模式 —— 模式中包含這兩個表。





          回頁首


          處理關系數據庫:結構化查詢語言

          SQL NULL 類型
          在開始創建數據庫表之前,必須知道列沒有指定值的時候要做什么。為了理解這一點,請想像一下填寫 Web 表單時的情況。如果某個具體列為空,那么插到數據庫中的是什么呢?可以想像,如果必須跟蹤無值 標記,問題會很麻煩。幸運的是,SQL 定義了一個特殊值,NULL,表示列沒有值。

          數據庫系統會成為軟件中復雜的部分,特別是在規模擴大到支持企業級應用程序的時候。所以,可以想像每個數據庫都會有自己的應用程序編程接口(API),而這些 API 可能彼此不同。當關系數據庫剛開發出來的時候,情況就是這樣。但是,幸運的是,許多開發商同意開發一個標準的語言,用來訪問和操縱數據庫。這個語言稱作結構化查詢語言(或 SQL,發音是 sea-quill)。至今已經形成了多個官方標準版本,包括 1992 年的版本,這一版被稱為 SQL-92,還有 1999 年的版本被稱為 SQL-99。Apache Derby 數據庫為 SQL-92 標準提供了幾乎完整的實現,所以用 Deryby 開發的應用程序可以容易地移植到其他數據庫系統。

          SQL 有兩個主要部分:數據定義語言(DDL)和數據操縱語言(DML)。DDL 命令用來創建、修改或刪除數據庫中的項目(例如表)。DML 命令用來在數據庫表中添加、修改、刪除或選擇數據。這篇文章后面的部分將提供對 SQL 的 DDL 部分的基本介紹。未來的文章將側重于 DML 命令和更高級的 DDL 命令。

          SQL 數據類型

          SQL 作為一個編程語言,定義了豐富的數據類型層次結構。數據庫已經變得更強大了,所以這個類型層次結構也變得更復雜。但是最簡單的數據庫并不要求使用所有允許的類型,通常只需要保存數值型、字符型和日期(或時間)數據。為了簡單,表 1、2、3、4 顯示了 Derby 中實現的基本 SQL 數據類型。

          如表 1 所示,Derby 提供了對三種整型數據類型的支持。這些類型由它們可以保存的整數的范圍區分,也就是由它們在數據庫中需要的存儲空間區分。在設計數據庫時要記住的一個關鍵問題就是,應當一直把表使用的空間控制在最小。一般來說,表越小,性能越高。但是必須能夠在生成的表中保存需要的數據。231 等于 2,147,483,648,263 等于 9,223,372,036,854,775,808,所以使用這些類型可以保存非常大的整數!

          表 1. Derby 中的基本整數數據類型
          數據類型 最小值 最大值 示例 說明
          SMALLINT -32768 (-215) 32767 (215 - 1) itemNumber SMALLINT 2 字節整數表示
          INT -231 231 - 1 itemNumber INT 4 字節整數表示
          BIGINT -263 263 - 1 itemNumber BIGINT 8 字節整數表示

          多數數值型數據不能用整數表示。Derby 對實數提供了多種格式的支持:單精度浮點、雙精度浮點以及準確的算術表示,如表 2 所示。

          表 2. Derby 中的基本數值類型
          數據類型 最小值 最大值 示例 說明
          REAL -3.402x10+38 3.402x10+38 price REAL IEEE 浮點數(4 字節)
          DOUBLE -1.79769x10+308 1.79769x10+308 price DOUBLE IEEE 浮點數(8 字節)
          DECIMAL 31 (最大精度) price DECIMAL(5,2) 準確算術表示

          如果從未遇到過準確精度數據類型,那么對算術類型和浮點類型可能有些迷惑。區別在于一個事實:計算機中使用的浮點數據類型無法包含每個實數。這看起來可能有些怪,但是想想實數的數量是無限的。大多數實數都無法保存在幾個字節的內存中。對于某些應用程序,精度的損失是可以接受的,而在許多情況下,則不可接受。例如,財務應用程序不能容忍僅僅因為某個數字不能保存在計算機中,就損失金錢。

          這個問題的解決方案是使用 DECIMAL 數據類型,它可以控制計算機存儲的數字位數(精度)和小數點后的位數(刻度)。要創建算術類型,應當指定保存的數據的精度,并可選地指定數據的刻度。DECIMAL 數據類型需要的存儲空間通常要比浮點數據類型大得多。所以應當小心地使用這個類型,否則應用程序的性能會降低。默認情況下,DECIMAL 類型的刻度為 0,這意味著 DECIMAL 數據類型模擬了整數類型。

          數值類型有多個同義詞。例如,DECIMAL 數據類型可以縮短為 DEC 或表示為 NUMERICDOUBLE 類型也可以表示為 DOUBLE PRECISION,雖然為什么在需要雙精度數字時要輸入額外的單詞,原因不明。更常用的同義詞是 FLOAT 類型,它擁有任意的浮點精度,可以在聲明數據類型時指定,例如 FLOAT(val)。精度必須是小于 53 的正整數;如果不是,就會出錯。如果指定了小于等于 23 的精度值,FLOAT(val) 就等價于 REAL;如果精度在 24 和 53 之間,那么 FLOAT(val) 等價于 DOUBLE

          除了數值類型,數據庫中最常用的保存數據的另一個類型是字符數據。字符數據的示例包括產品說明、人名或地址信息。Derby 提供了保存字符數據的兩個簡單技術:CHAR 類型和 VARCHAR 類型,詳情如表 3 所示。對于這兩種類型,都可以指定 length 參數,如果沒指定,默認為 1。在這兩個字符數據類型之間有兩個主要區別。首先,CHAR 類型的最大長度是 254 個字符,而 VARCHAR 類型最多可以容納 32,672 個字符。第二個區別比較微妙:CHAR 類型的長度總是指定的長度。如果沒有指定足夠的字符,那么會插入額外的空白來填滿剩余位置。而使用 VARCHAR 時,字符的數量是可變的,不執行額外的填充。

          表 3. Derby 中的基本字符串數據類型
          數據類型 最大長度 示例 說明
          CHAR 254 description CHAR(128) 定長字符串
          VARCHAR 32,672 description VARCHAR(128) 變長字符串

          因為長度可變,所以 VARCHAR 類型在實際的存儲空間方面會更有效率,但在性能上效率就會更低。CHAR 數據類型有助于性能提高,因為數據庫確切地知道每個 CHAR 列有多大,所以在讀寫數據時就可以執行某種性能優化。VARCHAR 列的最大長度看起來可能足夠大了,但是 Derby 還提供了更大的字符數據類型,這個類型將在未來的文章中討論。

          Derby 提供了最后一類簡單的數據類型來保存日期和時間,如表 4 所示。TIME 數據類型以 24 小時格式保存小時、分鐘和秒(HH:MM:SS)。DATE 數據類型保存月、日和年,可以用不同的格式指定,包括以下格式:

          • yyyy-mm-dd
          • mm/dd/yyyy
          • dd.mm.yyyy

           

          表 4. Derby 中的基本日期和時間數據類型
          數據類型 最小值 最大值 示例 說明
          TIME 00:00:00 24:00:00 start TIME 時間表示(精確到秒)
          DATE 0001-01-01 9999-12-31 stockDate DATE 日期表示(精確到天)

          Derby 還提供了 TIMESTAMP 數據類型,把 TIMEDATE 數據類型組合到一個類型中,表示準確的時間。





          回頁首


          在 Derby 中創建表

          目前為止,已經學習了如何設計表,包括規劃表的列和定義每個列的數據類型。在正確地設計了表之后,用 SQL 創建表的方法就很簡單了。清單 1 顯示了在 Derby 中創建表的正式語法。


          清單 1. Apache Derby 的 CREATE TABLE 語法
          --  Comment describing the purpose and layout of the table
                      CREATE TABLE [schemaName.]tableName (
                      { <columnDefinition> | <tableLevelConstraint>  } [,
                      { <columnDefinition> | <tableLevelConstraint>  }
                      ]*
                      ) ;
                      

          第一次看這個語法時,可能感覺到迷惑不解。但是有了基礎之后,接下來就容易了;而且如果想掌握 Derby,對正式語法的理解是必需的。方括號([])中的是可選參數。從正式語法中可以看出,模式名是可選的,在必需的頭一個列之后(創建連一個列都沒有的表是沒有意義的),其他列定義或表級約束都是可選的。

          您可能理解列定義的含義,但是可能不理解約束 的意義。約束有兩種類型:表級約束和列約束。約束通過某種方式對列或表進行限制。例如,可以用約束要求列總要有實際的值(沒有 NULL 值),或者列中的每個項必須是惟一的,或者列被自動分配默認值。在未來的文章中將更詳細地介紹約束。

          最后一個結束方括號之后的星號(*)代表可以包含一個或多個包含項。這意味著表必須有一個或多個列級或表級約束。豎線(|)表明 “可有可無” 條件。在這個語法示例中,必須定義一個新列或者定義一個表級約束。花括號({})把相關項組織在一起,而圓括號(())中是必需的元素 。最后,分號(;)表示 SQL 語句的結束。

          把這些規則投入使用則相當簡單。清單 2 顯示了如何用 Derby 提供的 ij 創建前面在 圖 1 中演示的表。


          清單 2. 在 Apache Derby 中創建表
          rb$ java org.apache.derby.tools.ij
                      ij version 10.1
                      ij> connect 'jdbc:derby:test;create=true' ;
                      ij> CREATE TABLE bigdog.products (
                      itemNumber INT NOT NULL,
                      price DECIMAL(5, 2),
                      stockDate DATE,
                      description VARCHAR(128)
                      ) ;
                      0 rows inserted/updated/deleted
                      ij> CREATE TABLE bigdog.vendors (
                      itemNumber INT NOT NULL,
                      vendorNumber INT NOT NULL,
                      vendorName CHAR(64)
                      ) ;
                      0 rows inserted/updated/deleted
                      ij> exit ;
                      

          與 Derby 數據庫進行交互的最簡單方式是使用 ij 工具,在這個系列的第一篇文章 “用 Apache Derby 進行開發 —— 取得節節勝利:Apache Derby 介紹”(developerWorks,2006 年 2 月)中已經介紹過。如果按照 清單 2 中的步驟進行,就會創建一個新的數據庫,名為 test。如果 test 數據庫已經存在,在發出 connect 語句時,會得到警告消息。可以安全地忽略這個警告。接下來,隱式地創建一個名為 bigdog 的新模式,并顯式地創建兩個新表 —— productsvendors —— 這兩個表保存在 bigdog 模式中。模式的創建所以是隱式的,是因為沒有發出 CREATE SCHEMA 語句。

          products 表有四個列:itemNumberpricestockDatedescriptionitemNumber 列提供了每個商品(或列)的惟一標識,它上面還有列級約束,強制要求提供正確的值(NOT NULL)。如果沒有這個要求,itemNumber 列就無法保持惟一,因為多個行都可能被分配 NULL 值。price 列創建為 DECIMAL 數據類型,精度為 5,刻度為 2。這意味著每個商品的最高價格可以是 $999.99。最后兩個列很簡單:stockDate 列以 Date 類型保存,description 列以字符串類型保存,最長 128 個字符,使用的空間是實際的字符串長度。

          vendors 表有三列:itemNumbervendorNumbervendorName。在這個示例中,itemNumbervendorNumber 列都有列級約束(NOT NULL)。另外,vendorName 列以字符串類型保存,最大長度為 64。因為 vendorName 列用 CHAR 數據類型保存,所以總是保留 64 個字符空間。

          在創建了各種項目之后,可能想知道是否有種簡單的方式可以查看數據庫中保存了什么項目。幸運的是,答案是肯定的,可以使用 dblook 工具。運行這個工具,如 清單 3 所示,提供了特定數據庫中已經創建的項目的詳細清單。


          清單 3. 用 dblook 查看模式
          rb$ java org.apache.derby.tools.dblook -d jdbc:derby:test
                      -- Timestamp: 2006-03-04 10:52:34.056
                      -- Source database is: test
                      -- Connection URL is: jdbc:derby:test
                      -- appendLogs: false
                      -- ----------------------------------------------
                      -- DDL Statements for schemas
                      -- ----------------------------------------------
                      CREATE SCHEMA "BIGDOG";
                      -- ----------------------------------------------
                      -- DDL Statements for tables
                      -- ----------------------------------------------
                      CREATE TABLE "BIGDOG"."PRODUCTS" (
                      "ITEMNUMBER" INTEGER NOT NULL,
                      "PRICE" DECIMAL(5,2),
                      "STOCKDATE" DATE,
                      "DESCRIPTION" VARCHAR(128));
                      CREATE TABLE "BIGDOG"."VENDORS" (
                      "ITEMNUMBER" INTEGER NOT NULL,
                      "VENDORNUMBER" INTEGER NOT NULL,
                      "VENDORNAME" CHAR(64));
                      

          dblook 工具是一個 Java 類,可以用它方便地把數據庫的內容輸出到控制臺。在命令行上運行它,就像運行其他 Java 程序一樣;惟一增加的就是使用 -d jdbc:derby:test 參數,這個參數指定 dblook 工具應當查詢的數據庫。如果能運行 ij 工具,那么 dblook 類文件就已經存在于 CLASSPATH 中了。如果不是這樣,請參考這個系列中的 第一篇文章,獲得正確設置 CLASSPATH 的詳細說明。正如 dblook 工具的輸出所示,test 數據庫包含 bigdog 模式,這個模式包含 productsvendors 表。另外,對這兩個表的列也有詳細描述。





          回頁首


          刪除 Derby 中的表

          沒有什么事情是完美的。當錯誤地創建了表或者表不再需要的時候,該怎么辦?簡單的答案是從數據庫中刪除表。而且,如果必要,再創建一個替代表。刪除表很容易,當然這意味著,在做這件事的時候應當非常小心 —— 不會彈出對話框要求您確認是否真的想刪除!

          從數據庫中刪除(或者更正式地說,撤下(drop))一個表的完整語法是:

          DROP TABLE [schemaName.]tableName ;

          語法很簡單:把完全限定名稱和分號放在 DROP TABLE SQL 命令后面,就完成了。清單 4 中在新創建的臨時表上演示了刪除表的過程。


          清單 4. 從 Derby 數據庫刪除表
          rb$ java org.apache.derby.tools.ij
                      ij version 10.1
                      ij> connect 'jdbc:derby:test' ;
                      ij> CREATE TABLE temp ( aColumn INT ) ;
                      0 rows inserted/updated/deleted
                      ij> DROP TABLE temp ;
                      0 rows inserted/updated/deleted
                      ij> exit ;
                      





          回頁首


          結束語

          現在您已經走上了操作 Apache Derby 數據庫的道路。目前您已經掌握了基本的數據庫概念,包括模式、表和列,還看到了使用名為 Bigdog's Surf Shop 的虛擬公司對這些概念的演示。要操作像 Derby 這樣的數據庫,需要學習 SQL,它是與數據庫進行交互的標準語言。這篇文章還介紹了可以用來在 Derby 數據庫中保存數據的基本數據類型。把這些概念融合在一起,您學習了如何用 Derby 創建和刪除表,還使用 Derby 的 dblook 工具輸出了數據庫的模式內容。

          posted on 2007-11-27 23:05 smildlzj 閱讀(600) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 大邑县| 那曲县| 大庆市| 犍为县| 马龙县| 扎兰屯市| 建瓯市| 井陉县| 石河子市| 黄冈市| 石柱| 临猗县| 彩票| 都江堰市| 商河县| 扬州市| 庆城县| 新津县| 明星| 永春县| 澄迈县| 深泽县| 长丰县| 隆昌县| 武清区| 苏尼特左旗| 印江| 壶关县| 内乡县| 鲁山县| 苍山县| 绥江县| 甘德县| 荃湾区| 贺兰县| 宣汉县| 淅川县| 宁阳县| 东光县| 丁青县| 南城县|