- 1、表
- 1.1、創建表
- 1.2、表重命名 & 刪除表
- 2、字段
- 2.1、添加字段
- 2.2、修改字段 & 刪除字段
- 3、注釋
- 4、約束
- 4.1、添加主鍵約束
- 4.2、添加外鍵約束
- 4.3、添加唯一約束
- 4.4、添加 CHECK 約束
- 4.5、空約束和非空約束
- 4.6、禁用約束 & 啟用約束 & 刪除約束
- 5、索引
- 5.1、創建索引
- 5.2、修改索引 & 刪除索引
- 6、總結
在 Oracle 中表的類型有 9 種,但實際應用中 99% 以上的情況下用的可能都是堆組織表,也就是我們常說的“普通”表。執行普通 CREATE TABLE 語句時,默認得到的表就是堆組織表。表是數據庫中一個非常重要的對象,是其他對象的基礎。數據庫只是一個框架,表才是其實質內容。本文內容將圍繞表及表相關的 SQL 操作展開。
1、表
1.1、創建表
在 Oracle 中創建表語法有兩種,一種是不依賴現有表創建全新的表,另一種是根據現有表創建類似的新表。無論是哪一種寫法,都得遵守一些最基本的規則:
- 1、表名和列名都必須是字母開頭。
- 2、表名和列名的長度都必須是 1~30 個字符。
- 3、表名和列表中必須由 AZ、az、0~9、_、$、# 組成,不能使用空格和單引號等特殊字符。
- 4、同一 Schema 下不能有重復的表名,同一張表中不能有重復的列名。
- 5、表名和列表不能是部分關鍵字,如 TABLE、VIEW、AUDIT 等。
- 6、創建表的用戶必須具有 CREATE TABLE 的權限。
- 7、必須要有足夠的存儲空間。
方式 1:如要創建一張課程表,字段包含:課程ID、課程名稱、課程描述。示例:
CREATE TABLE t_course(
course_id NUMBER(10) PRIMARY KEY,
course_name VARCHAR2(50),
course_desc VARCHAR2(2000)
);
方式 2:如要創建一張只包含職員姓名和生日的表,示例:
CREATE TABLE t_staff_mini AS
SELECT t1.staff_id, t1.birthday FROM t_staff t1;
方式 2:如要創建一張只包含 90 后員工數據的職員表,示例:
CREATE TABLE t_staff90 AS
SELECT * FROM t_staff t1 WHERE t1.birthday>=TO_DATE('1990-01-01','yyyy-mm-dd');
如上例所示,根據已有表創建一張新表的語法是——CREATE TABLE ... AS SELECT * FROM ...
,關於這個語法有兩點需要注意:
- 只創建表結構並拷貝表數據,不拷貝任何約束。
- 當 WHERE 條件不成立時,只創建表結構,不拷貝表數據。
1.2、表重命名 & 刪除表
將表名從 t_staff_mini
改成 t_staff2
,示例:
ALTER TABLE t_staff_mini RENAME TO t_staff2;
刪除 t_staff90
表,示例:
DROP TABLE t_staff90; -- 普通刪除,將表放入回收站
DROP TABLE t_staff90 PURGE; -- 徹底刪除,將清除相關表信息
2、字段
2.1、添加字段
向 t_staff2
表中添加 is_disabled
字段,默認值 0,表示職員未被禁用,即啟用狀態,示例:
ALTER TABLE t_staff2 ADD(is_disabled NUMBER(1) DEFAULT(0)); -- DEFAULT 的括號可以省略
向 t_staff
表中添加性別、身高和體重 3 個字段,寫三條語句分別來添加當然是可以的,但 Oracle 提供了更簡潔的語法,示例:
ALTER TABLE t_staff2 ADD(gender NUMBER(1), height NUMBER(4,1), weight NUMBER(4,1));
2.2、修改字段 & 刪除字段
把 t_staff
表中的 is_disabled
字段的字段名改為 staff_status
,示例:
ALTER TABLE t_staff2 RENAME COLUMN is_disabled TO staff_status;
把 t_staff
表中的 gender
字段的數據類型改為 VARCHAR2
,示例:
ALTER TABLE t_staff2 MODIFY(gender VARCHAR2(10)); -- MODIFY 的括號可以省略
把 t_staff
表中的 gender
字段的數據類型長度擴大 5 倍,示例:
ALTER TABLE t_staff2 MODIFY(gender VARCHAR2(50));
把 t_staff
表中的 staff_status
字段的默認值改為字符串 1,示例:
ALTER TABLE t_staff2 MODIFY(staff_status DEFAULT('1'));
刪除 t_staff
表中的 gender
字段,示例:
ALTER TABLE t_staff2 DROP(gender);
刪除 t_staff
表中的身高和體重兩個字段,與添加多個字段同理,示例:
ALTER TABLE t_staff2 DROP(height,weight);
3、注釋
注釋表示例:
COMMENT ON TABLE t_staff IS '職員表'; -- 給 t_staff 表添加注釋
COMMENT ON TABLE t_staff IS ''; -- 清空 t_staff 表的注釋,可利用這個思路實現刪改表注釋的效果
注釋字段示例:
COMMENT ON COLUMN t_staff.staff_name IS '職員姓名'; -- 給 t_staff.staff_name 字段添加注釋
COMMENT ON COLUMN t_staff.staff_name IS ''; -- 清空 staff_name 字段的注釋,可利用這個思路實現刪改字段注釋的效果
4、約束
數據的完整性用於確保數據庫數據遵從一定的商業和邏輯規則。在 Oracle 中數據完整性可以通過約束、觸發器、存儲過程、函數等方式來實現,而約束易於維護,並且具有最好的性能,一般作為確保數據完整性的首選。
4.1、添加主鍵約束
要求給 t_staff_copy
表添加一個主鍵,主鍵字段為 staff_id
,示例:
ALTER TABLE t_staff_copy ADD CONSTRAINT pk_staff_copy PRIMARY KEY(staff_id);
如要根據職員姓名和性別創建一個聯合主鍵,示例:
ALTER TABLE t_staff_copy DROP CONSTRAINT pk_staff_copy; -- 表只能有一個主鍵,所以要先把剛才建的主鍵刪除掉
ALTER TABLE t_staff_copy ADD CONSTRAINT pk_staff_copy PRIMARY KEY(staff_name,gender);
實際開發中一般都會給表設置主鍵,而且大部分都是在創建表的時候一塊兒創建,示例:
-- 語法一
CREATE TABLE t_staff3(
staff_id NUMBER(10) PRIMARY KEY,
staff_name VARCHAR2(20)
);
-- 語法二
CREATE TABLE t_staff4(
staff_id NUMBER(10),
staff_name VARCHAR2(20),
CONSTRAINT pk_staff4 PRIMARY KEY(staff_id)
);
4.2、添加外鍵約束
關於外鍵約束有兩個需要注意的概念,分別是級聯更新和級聯刪除,簡單的說就是當主表中數據刪除后,會同步更新或刪除從表中的數據。在 Oracle 里刪除有外鍵約束的主表數據,會有以下三種情況之一發生:
- 1、禁止刪除,也是 Oracle 默認行為。
- 2、參照主表把從表中對應的數據一同刪除。適合強耦合關系。
- 3、參照主表把從表中對應的數據設置為空。適合弱耦合關系。
第 1 種情況示例:
ALTER TABLE t_field_enum ADD CONSTRAINT fk_field_code FOREIGN KEY(field_code) REFERENCES t_field(field_code);
第 2 種情況示例:
ALTER TABLE t_field_enum DROP CONSTRAINT fk_field_code; -- 對同一個字段只能建一個外鍵,所以要先把剛才建的外鍵刪除掉
ALTER TABLE t_field_enum ADD CONSTRAINT fk_field_code FOREIGN KEY(field_code) REFERENCES t_field(field_code) ON DELETE CASCADE;
第 3 種情況示例:
ALTER TABLE t_field_enum DROP CONSTRAINT fk_field_code;
ALTER TABLE t_field_enum ADD CONSTRAINT fk_field_code FOREIGN KEY(field_code) REFERENCES t_field(field_code) ON DELETE SET NULL;
4.3、添加唯一約束
唯一約束的作用就是確保表字段的值不會重復,示例:
ALTER TABLE t_staff ADD CONSTRAINT uk_staff_name UNIQUE(staff_name);
4.4、添加 CHECK 約束
CHECK 約束允許對表字段做更個性化的約束以滿足業務需要,比如限定性別只能是 1(男)和 0(女),示例:
ALTER TABLE t_staff ADD CONSTRAINT ck_gender CHECK(gender IN(0,1));
4.5、空約束和非空約束
空約束和非空約束比較特殊,它們的作用就是限制表字段非必填或必填,對應的語法關鍵字分別是 NULL 和 NOT NULL,用法完全一樣。添加非空約束示例:
ALTER TABLE t_staff2 MODIFY(staff_status NOT NULL);
盡管添加或修改空約束和非空約束的語法很簡單,但實際開發中卻有很多細節問題需要注意,具體規則將在.Net程序員學用Oracle系列(15):DUAL、NULL、ROWID中講述。
4.6、禁用約束 & 啟用約束 & 刪除約束
除非空約束比較特殊以外,其它約束的啟用、禁用和刪除語法都以一樣的。示例:
ALTER TABLE t_staff DISABLE CONSTRAINT uk_staff_name; -- 禁用 uk_staff_name 約束
ALTER TABLE t_staff ENABLE CONSTRAINT uk_staff_name; -- 啟用 uk_staff_name 約束
ALTER TABLE t_staff RENAME CONSTRAINT uk_staff_name TO uk_test; -- 將約束名從 uk_staff_name 改成 uk_test
ALTER TABLE t_staff DROP CONSTRAINT uk_test; -- 刪除 uk_staff_name 約束
5、索引
索引其實是一個很大的話題,大型應用這塊兒工作主要由 DBA 來完成,還有些索引 Oracle 會自動創建(比如創建主鍵時會自動創建基於主鍵字段的唯一索引,創建唯一約束時會創建基於約束字段的唯一索引),這里僅介紹創建、禁用和刪除索引的語法,作為普通開發人員知道這些已經夠了。
5.1、創建索引
索引一般是根據業務查詢條件來創建的,常見的 Oracle 索引創建語法示例:
CREATE INDEX idx_manager_id ON t_staff(manager_id); -- 創建標准/普通索引
CREATE UNIQUE INDEX uk_staff_name ON t_staff(staff_name); -- 創建唯一索引
CREATE BITMAP INDEX idx_gender ON t_staff(gender); -- 創建位圖索引
CREATE INDEX idx_status ON t_staff(DECODE(is_disabled,0,0,NULL)); -- 創建基於函數的索引
CREATE INDEX idx_birthday ON t_staff(birthday) REVERSE; -- 創建反向鍵索引
索引有單列索引和組合索引之分,上面 5 個索引都屬於單列索引,如果要創建組合索引,即在多個列上創建索引,只要在上面創建索引的語句中括號里加入更多字段並用逗號隔開即可。
5.2、修改索引 & 刪除索引
修改索引:創建索引時還可以指定表空間,修改時也能調整表空間等索引屬性,下面只示例幾個本人用過的語法:
ALTER INDEX idx_manager_id UNUSABLE; -- 禁用索引
ALTER INDEX idx_manager_id REBUILD REVERSE; -- 將普通索引修改為反向鍵索引
ALTER INDEX idx_manager_id REBUILD NOREVERSE; -- 將反向鍵索引修改為普通索引
ALTER INDEX idx_manager_id RENAME TO idx_test; -- 將索引名從 idx_staff_name 改成 idx_test
刪除索引:如果發現索引建錯了也可以直接刪除掉,示例:
DROP INDEX idx_test;
6、總結
本文主要介紹了關於表的常見 SQL 語法,不知道大家有沒有發現如下兩個規律:
規律一:當成功創建一個主鍵約束之后,Oracle 會自動基於相同的字段列表再創建一個同名的唯一索引,反之不會。
規律二:當成功創建一個唯一約束之后,Oracle 會自動基於相同的字段列表再創建一個同名的唯一索引,反之不會。
本文鏈接:http://www.cnblogs.com/hanzongze/p/oracle-table-field.html
版權聲明:本文為博客園博主 韓宗澤 原創,作者保留署名權!歡迎通過轉載、演繹或其它傳播方式來使用本文,但必須在明顯位置給出作者署名和本文鏈接!本人初寫博客,水平有限,若有不當之處,敬請批評指正,謝謝!