第二章 创建和使用数据库
首先,需要说明的是,在学习SQL时,我是通过MySQL这一开源数据库服务器来学习如何编写SQL语句,但目光并不能仅限于此,在甲骨文公司上的Oracle Database,Microsoft上的SQL Server,IBM上的DB2 Universal Database 和Sybase的Sybase Adaptive Server也要熟悉把握各中特色与差异。
2.1创建MySQL数据库
Create USER 'learning'@'localhost' IDENTIFIED BY 'password'; #创建用户
GRANT ALL PRIVILEGES ON bank.* TO 'learning'@'localhost'; #赋予用户bank数据库的权限
quit;
mysql -u learning -p;
USE bank;
2.2 使用mysql命令行工具
mysql命令行工具使用+、-和|等符号将查询结果格式化输出在矩形框中。
SELECT now();#显示当前日期时间
SELECT now()
-> FROM dual;#某些数据库服务器(如Oracle)规定查询语句中必须包含FROM,Oracle与mysql都自带了dual中只包含了dummy一个列。
2.3 MySQL数据类型
对于流行数据库,字符串、日期与数字等都有着相同的数据类型,但对于XML文档及二进制文档,不同数据库可能存在着较大差异(这些咱们暂不涉及)。
2.3.1 字符型数据
字符型数据可以使用定长或变长字符串实现。定长:使用空格向右填充;变长:不填充且字节数可变。
如char(20)#定长字符串,最大长度255字节,varchar(20)#变长字符串,最大长度65535字节
1)字符集
对于拉丁系语言,如英语,通常是一个字母一个字节(单字符集);其他语言如日语韩语,一个字符往往多个字节(多字符集);
SHOW CHARACTER SET;#查看服务器所支持的字符集
+----------+---------------------------------+---------------------+--------+
| Charset | Description | Default collation | Maxlen |
+----------+---------------------------------+---------------------+--------+
| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
| ascii | US ASCII | ascii_general_ci | 1 |
| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
| binary | Binary pseudo charset | binary | 1 |
| cp1250 | Windows Central European | cp1250_general_ci | 1 |
| cp1251 | Windows Cyrillic | cp1251_general_ci | 1 |
| cp1256 | Windows Arabic | cp1256_general_ci | 1 |
| cp1257 | Windows Baltic | cp1257_general_ci | 1 |
| cp850 | DOS West European | cp850_general_ci | 1 |
| cp852 | DOS Central European | cp852_general_ci | 1 |
| cp866 | DOS Russian | cp866_general_ci | 1 |
| cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 |
| dec8 | DEC West European | dec8_swedish_ci | 1 |
| eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 |
| euckr | EUC-KR Korean | euckr_korean_ci | 2 |
| gb18030 | China National Standard GB18030 | gb18030_chinese_ci | 4 |
| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
| geostd8 | GEOSTD8 Georgian | geostd8_general_ci | 1 |
| greek | ISO 8859-7 Greek | greek_general_ci | 1 |
| hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 |
| hp8 | HP West European | hp8_english_ci | 1 |
| keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | 1 |
| koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 |
| koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 |
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
| macce | Mac Central European | macce_general_ci | 1 |
| macroman | Mac West European | macroman_general_ci | 1 |
| sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 |
| swe7 | 7bit Swedish | swe7_swedish_ci | 1 |
| tis620 | TIS620 Thai | tis620_thai_ci | 1 |
| ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 |
| ujis | EUC-JP Japanese | ujis_japanese_ci | 3 |
| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
| utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 |
| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
| utf8mb4 | UTF-8 Unicode | utf8mb4_0900_ai_ci | 4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.00 sec)
#这里面的Maxlen若大于1则表示多字符集;latin1为MySQL的默认字符集;
在mysql中还可以为数据库字符列选择不同的字符集,如:
varchar(20) CHARACTER SET utf8;
CREATE DATABASE foreign_sales CHARACTER SET utf8;#为整个数据库更改默认字符集
2)文本数据
如果存储的数据超过64k(varchar列所能容许的上限),就要用到文本类型。
文本类型 | 字节最大长度 |
---|---|
tinytext | 255 |
text | 65535 |
mediumtext | 16777215 |
longtext | 429496295 |
注:
- 超过文本数据最大长度的数据会被截断;
- 向文本列装载数据时,不会消除数据的尾部空格
- 当时用文本列排序或分组时,一般只使用前1024个字节
- 上表针对MySQL,SQLServer对字符串型数据只提供text类型,而DB2和Oracle使用的数据类型名称为colb。
- 由于varchar的存在,一般在MySQL中不会用到tinytext和text
2.3.2 数值型数据
整数类型
类型 | 带符号的范围 | 无符号的范围 |
---|---|---|
tiny | -128~127 | 0~255 |
smallint | -32768~32767 | 0~65535 |
mediumint | -8388608~8388607 | 0~16777215 |
int | -2147483648~2147483647 | 0~4294967295 |
bigint | -9223372036854775808~9223372036854775807 | 0~18446744073709551615 |
MySQL浮点型:float(p,s);double(p,s);p:精度(总位数),s:有效位(数)
2.3.3 时间数据
MySQL时间类型
类型 | 默认格式 | 类型 | 默认格式 |
---|---|---|---|
date | YYYY-MM-DD | datatime | YYYY-MM-DD HH:MI:SS |
timestamp | YYYY-MM-DD HH:MI:SS | year | YYYY |
time | HHH:MI:SS |
其中要注意的是date与datetime范围包括9000年,timestamp只包括1970-2037,year只包括19012155,time只包括-839:59:59839:59:59
2.4 表的创建
2.4.1 step1 设计
我们需要哪些信息,它们分别是什么类型
2.4.2 step2 精化
拒绝重复,复合,保证行唯一,对外键的设计
2.4.3 step3 构建SQL方案语句
CREATE TABLE person
(person_id SMALLINT UNSIGNED,
fname VARCHAR(20),
lname VARCHAR(20),
gender ENUM('M','F'),
brith_date DATE,
street VARCHAR(30),
city VARCHAR(20),
state VARCHAR(20),
country VARCHAR(20),
postal_code VARCHAR(20),
CONSTRAINT pk_person PRIMARY KEY (person_id)
);
gender ENUM(‘M’,‘F’)#约束gender的取值
CONSTRAINT pk_person PRIMARY KEY (person_id) #在定义表时,需要向数据库指明哪个列或哪些列将作为表的主键,constraint就是这个功能。该语句表明person_id 为主键并被命名为pk_person。
CREATE TABLE favorite_food(
person_id SMALLINT UNSIGNED,
food VARCHAR(20),
CONSTRAINT pk_fav_food PRIMARY KEY (person_id,food),
CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id)
REFERENCES person (person_id)
);
REFERENCES person (person_id)#外键约束,限定person_id必须来自person。
##2.5 操作与修改表
2.5.1 insert data
生成数字型主键数据
修改已存在的表定义:
ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT;
上述语法表示将person_id赋值为null时,MySQL自动添加可用的主键数字;
添加,查询数据:
INSERT INTO person
(person_id,fname,lname,gender,birth_date)
VALUES(null,'William','Turner','M','1996-04-25');
SELECT person_id,fname,lname,birth_date FROM person WHERE person_id=1;
SELECT person_id,fname,lname,birth_date FROM person WHERE lname='Turner';
INSERT INTO favorite_food(person_id,food) VALUES(1,'pizza');
INSERT INTO favorite_food(person_id,food) VALUES(1,'cookies');
INSERT INTO favorite_food(person_id,food) VALUES(1,'nachos');
SELECT food FROM favorite_food WHERE person_id=1 ORDER BY food;
INSERT INTO person
(person_id,fname,lname,gender,birth_date,
street,city,state,country,postal_code)
VALUES(null,'Moon','Left','F','1996-04-25','Mao','JJ','JX','China','332000');
更新数据:
UPDATE person
SET street='1225 Trement St.',
city='Boston',
state='VA',
country='USA',
postal_code='02138'
WHERE person_id=1;
注:这里要注意WHERE前面最后一个赋值语句不用打逗号,我卡这里卡了1个小时你能信…
删除数据:
DELETE FROM person
WHERE person_id=2;