主要介紹一下個人對主鍵(primary key)、外鍵(foreign key)、候選鍵(Candidate key)、超鍵(super key)、references的總結
概念:
主鍵:用戶選擇元組標識的一個候選鍵,主鍵不允許為空
外鍵:來描述兩個表的關系,外鍵可為空
超鍵:能唯一的標識元組的屬性集
候選鍵:不含有多余屬性的超鍵
實例:
假如有以下學生和教師兩個表:
Student(student_no,student_name,student_age,student_sex,student_credit,teacher_no)
Teacher(teacher_no,teacher_name,teacher_salary)
超鍵:Student表中可根據學生編號(student_no),或身份證號(student_credit),或(學生編號,姓名)(student_no,student_name),或(學生編號,身份證號)(student_no,student_credit)等來唯一確定是哪一個學生,因此這些組合都可以作為此表的超鍵
候選鍵:候選鍵屬於超鍵,且是最小的超鍵,即如果去掉超鍵組合中任意一個屬性就不再是超鍵了。Student表中候選鍵為學生編號(student_no),身份證號(student_credit)
主鍵:主鍵是候選鍵中的一個,可人為決定,通常會選擇編號來作為表的主鍵。現分別選取student_no,teacher_no作為Student表,Teacher表的主鍵
外鍵:teacher_no為兩個表的公共關鍵字,且是Teacher表的主鍵,因此teacher_no是Student表的外鍵,用來描述Student表和Teacher表的關系
--References用法
創建一張Student表:
Create table Student(
student_no number(10) not null,
student_name varchar2(10) not null,
student_age number(4) not null,
student_sex varchar2(4) not null,
student_credit varchar2(18) not null,
teacher_no number(10) not null,
constraint PK_Student primary key(student_no) --設置主鍵
);
創建一張Teacher表:
Create table Teacher(
teacher_no number(10) not null,
teacher_name varchar2(10) not null,
teacher_salary number(10) not null,
constraint PK_Teacher primary key(teacher_no) --設置主鍵
);
--創建外鍵約束
alter table Student add constraint FK_Student_References_Teacher (teacher_no) references Teacher(teacher_no);
1.primary key
☆如果一個table有primary key,那么這個primary key 的value就不能為null,而且每條record就不能重復(完全相同),否則會發生如下錯誤
A.當primary key置為null時:ERROR 1048 (23000): Column 'id' cannot be null
B.當primary key 重復時:ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
例子:create table t2 ( id int(4) not null primary key, --auto_increment, name char(20) not null, sex int(4) not null default '0', degree double(16,2));
A.的sql語句:insert t2 values(1,'www',1,99.8);當執行兩遍時報錯
B.的sql語句:insert t2 values(null,'www',1,99.8);
結果:select * from t2;
+----+--------+------+----------+
| id | name | sex | degree |
+----+--------+------+----------+
| 1 | www | 1 | 99.80 |
+----+--------+------+----------+
否則,當table無primary key時
語句:create table t1 ( id int(4), name char(20));
C.insert t1 values (1,'www');可以執行n遍
D.insert t1 values (null,'www');也可以執行n遍
結果:select * from t1;
+--------+---------+
| id | name |
+--------+---------+
| 1 | www |
| 1 | www |
| NULL | www |
+--------+--------+
2.foreign key
外鍵的使用條件有三個
① 兩個表必須是InnoDB表,MyISAM表暫時不支持外鍵
② 外鍵列必須建立了索引,MySQL 4.1.2以后的版本在建立外鍵時會自動創建索引,但如果在較早的版本則需要顯式建立;
③ 外鍵關系的兩個表的列必須是數據類型相似,也就是可以相互轉換類型的列,比如int和tinyint可以,而int和char則不可以;
我們建立一個table:create table t1 ( id int(4), name char(20))type=innodb;並且建立索引create index t1_index on t1(name);
然后再建一個table:create table t3( id int(4),name char(20),foreign key(name) references t1(name)type=innodb );
那么 insert t3 values(1,'aaa');就會報錯:ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`anwei`.`t3`, CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`name`) REFERENCES `t1` (`name`))
但是在完成insert t1 values(1,'aaa');后就可以了,也就是values(1,'aaa');就不報錯了,但是其他那么的值就又會報錯的了。
說明:name是容許null值的,所以null值不受限制。
---------------------
創建一個字段,首先是字段名,然后是字段數據類型,后面的就是對此字段的約束,一般有not null ,unsigned,auto_increment,default 等等。
然后挨個解釋題目中的五個概念
unique key:在一張表中可以標識一個列或多個列,因此它既可以看做列級約束、也可以看做表級約束。 用來限制一個列中所有元素都不重復,列元素可以為null。
primary key:在一張表中只能有一個,來約束該列中所有元素不重復,且不能為null。
以上兩者聯系與區別:primary = unique + not null 是一個可取的說法;primary是一個索引,當系統要查詢表中某條記錄時,可以通過primary key標記的列,快速查詢到所需的記錄,所以這里primary修飾的列一般都是事先規定好,就是用來進行索引的列,比如:id int unsigned not null auto_increment; 這種列。 而unique key 只是用來限制列元素不重復,並不一定用來快速檢索,比如:我們想保證一個表中“身份證”字段的每一條記錄不重復 or “電話號”字段每一條記錄不重復,就可以用unique進行約束,而此時這樣的列跟索引查找並沒有關系。
foreign key:一個表中的 foreign key 指向另一個表中的 unique key (當然也可以是primary key,而且一般就應該是primary key吧,畢竟primary key沒null的值)。就是一張表中,foreign標識的列,其中每一個元素,都能對應到另一張表中unique標識的列元素。
index / key :兩者一般可以划等號,同等看待。其功能:如果要像primary key標識的字段一樣,能夠利用索引快速的查詢得到結果怎么辦?primary key一張表只能設置一個,此時就可以用index / key 來給一個字段列加索引,從而大大加快該列中元素的查找速度。
---------------------
trunc 函數可用於截取日期時間
用法:trunc(字段名,精度)
具體實例:
在表table1中,有一個字段名為sysdate,該行id=123,日期顯示:2016/10/28 15:11:58
1、截取時間到年時,sql語句如下:
select trunc(sysdate,'yyyy') from table1 where id=123; --yyyy也可用year替換
顯示:2016/1/1
2、截取時間到月時,sql語句:
select trunc(sysdate,'mm') from table1 where id=123;
顯示:2016/10/1
3、截取時間到日時,sql語句:
select trunc(sysdate,'dd') from table1 where id=123;
顯示:2016/10/28
4、截取時間到小時時,sql語句:
select trunc(sysdate,'hh') from table1 where id=123;
顯示:2016/10/28 15:00:00
5、截取時間到分鍾時,sql語句:
select trunc(sysdate,'mi') from table1 where id=123;
顯示:2016/10/28 15:11:00
6、截取時間到秒暫時不知道怎么操作
7、不可直接用trunc(sysdate,'yyyy-mm-dd'),會提示“精度說明符過多”
