SQL学习指南——创建和填充数据库

1 使用命令行工具

启动命令行工具mysql的时候,可以同时指定要使用的用户名和数据库

bash 复制代码
mysql -uroot -p123456 sakila

查看当前日期和时间

bash 复制代码
select now();

某些数据库服务器要求查询语句中必须包含from子句,并在其中至少指明一个数据表,比如广泛使用的Oracle Database,如果只是调用函数,Oracle为此提供了一个特殊的数据表dual,该数据表仅由dummy的一列组成,并且只包含一行,为了与Oracle Database兼容,MySQL也提供了dual数据表,之前获取当前日期和时间的查询也可以写作

如果没有使用Oracle Database,也不需要与其保持兼容,那么完全可以忽略dual数据表,只使用不包含from子句的select语句

注意:

dual 是 Oracle 数据库的虚拟表,MySQL 为了兼容 SQL 语法,虽然支持 SELECT ... FROM dual 这种写法,但它并不是一个真实存在的表,所以用 SELECT * FROM dual 就会报错。

用了命令行工具mysql之后,只需要输入quit或者exit就可以返回windows或UNIX shell

2 MySQL数据类型

这里只涉及简单数据类型,字符型、日期型和数值型

字符型数据

字符型数据可以使用定长或变长字符串来存储,两者的不同点在于定长字符串会使用空格向右填充,并始终占用同样数量的字节;变长字符串不需要向右填充,且占用的字节数不固定,在定义字符型的列时,必须指定该列所能存储字符串的最大长度

采用定长字符串的列,目前允许的最大长度为255字节,而采用变长字符串的列,最大长度则为65535字节,如果需要存储更长的字符串,则要使用某种文本类型(mediumtex和longtext)。一般来说,如果列中存储的所有字符串长度都一样(比如州的缩写),应该使用char类型,如果字符串长度各不相同,则应该使用varchar类型,char和varchar类型的用法在主流数据库服务器中都差不多

注意:在Oracle Database中使用varchar时会导致异常,Oracle用户在定义变长字符串列的时候应该使用varchar2

字符集

MySQL8之前,MySQL服务器默认字符集是latin1,但在版本8中改为了utf8mb4

MySQL 早期偷懒,自己搞了个阉割版,起名叫 utf8,只做到 3 字节(不支持 emoji 表情、部分生僻汉字、特殊符号)

后来为了兼容完整 4 字节,新增了 utf8mb4(mb4 = most bytes 4)(支持所有 emoji、所有生僻字、全世界所有字符)

文本数据

如果需要存储的数据超出了varchar类型的最大长度(64KB),则需要使用文本类型

MySQL文本类型及其最大长度

文本类型 最大长度/字节
tinytext 255
text 65535
mediumtext 16777215
longtext 4294967295

注意:

  1. 如果所加载的数据超出了文本列类型的最大长度,会被截断
  2. 在加载时,文本列数据尾部的空格不会被删除
  3. 在对text类型的文本进行排序或分组时,只使用前1024字节,不过该限制量可以根据需要增加
  4. 上面表格仅针对MySQL,对于较大的字符数据,SQL Server使用单一的text类型,而DB2和Oracle使用名为clob(Character Large Object)的数据类型
  5. 目前MySQL允许varchar类型的最大长度为65535字节(4.0版本中为255字节),一般情况下没有什么必要再使用tinytext或text类型了

数值型数据

最常用的是存储整数的数值类型,在这种类型前面可以加上unsigned,以通知服务器该列中存储的所有数据均大于或等于0

MySQL的整数类型

类型 signed的取值范围 unsigned的取值范围
tinyint -128~127 0~255
smallint -32768~32767 0~65535
mediumint -8388608~8388607 0~16777215
int -2147483648~2147483647 0~4294967295
bigint -2^63~2的63次方-1 0~2^64-1

如果使用上述整数类型创建列,MySQL会为数据分配适合的存储空间,从1字节(tinyint)到8字节(bigint)。因此,应该选择正好能够容纳要保存的最大数值的类型,以避免浪费存储空间

时间型数据

MySQL的时间数据类型

类型 默认格式 取值范围
date YYYY-MM-DD 1000-01-01~9999-12-31
datetime YYYY-MM-DD HH:MI:SS 1000-01-01 00:00:00.000000 ~ 9999-12-31 23:59:59.999999
timestamp YYYY-MM-DD HH:MI:SS 1970-01-01 00:00:00.000000 ~ 2038-01-18 22:14:07.999999
year YYYY 1901~2155
time HHH:MI:SS -838:59:59.000000 ~ 838:59:59.000000

创建数据表

person数据表

类型 允许的值
name varchar(40)
eye_color char(2) BL、BR、GR
birth_date date
address varchar(100)
favourite_foods varchar(200)

改进

在设计数据库时要确保不出现重复列(不包括外键)或复合列,检查person表,存在以下问题

  1. name列实际上是一个包含姓氏和名字的复合列
  2. 因为不止一个人可以拥有相同的姓名,眼睛颜色,出生日期等,所以person数据表中缺少可以保证唯一性的列
  3. address列同样是包含街道、城市、州/省、国家/地区、邮政编码的复合列
  4. favorite_foods列可以包含0个,1个或更多条目的列表,最好是为其创建单独的数据表,在其中加入指向person数据表的外键,以便知道特定的食物是哪个人的属性

在创建表的时候,可以添加检查约束(check constraint)来限制特定列的值,如下所示:

bash 复制代码
eye_color char(2) check (eye_color in ('BR','BL','GR'))

实际上,MySQL提供了另一种名为enum的字符数据类型,将检查约束并入了数据类型定义:

bash 复制代码
eye_color enum('BR','BL','GR')

外键的核心定义

一张表的外键,必须指向另一张表的主键

  • 外键所在的表叫从表(子表)
  • 被指向的表叫主表(父表)

子表这个外键字段,只能填主表主键里已经有的值

填充和修改数据表

插入数据

生成数值型主键数据

在MySQL中,只需要简单地为主键列启用自增特性,通常来说,应该在创建数据表时就完成此项工作,也可以用alter来修改已有的数据表定义

bash 复制代码
alter table person modify person_id smallint unsigned auto_increment;

此时向person数据表插入数据时,只需向person_id列提供null值,MySQL会用下一个可用数值填充该列(默认情况下,MySQL从1开始自增)

查看引擎

bash 复制代码
SHOW ENGINES;

执行后会看到:

Support 列:DEFAULT 就是当前默认引擎

常见引擎:InnoDB(默认)、MyISAM、MEMORY 等

相关推荐
倔强的石头_4 小时前
kingbase备份与恢复实战(七)—— 恢复演练与验收:从“能恢复”到“可交付预案”
数据库
满昕欢喜4 小时前
第2章 SQL Server 2019服务器管理
数据库·sqlserver
giaz14n9X4 小时前
Redis 分布式锁进阶第五十一篇
数据库·redis·分布式
念越4 小时前
【数据库系统概论期末复习】第四章 数据库安全性重点与常考题整理
数据库·数据库系统概论
拾贰_C5 小时前
【mysql | windows | installation】 MySQL5.安装
数据库·windows·mysql
睡不醒男孩0308235 小时前
达梦数据安装详细步骤(包含CLup一键部署达梦数据库实例)
数据库·达梦·clup
真实的菜5 小时前
【无标题】Redis 从入门到精通(七):缓存设计与最佳实践 —— 穿透、击穿、雪崩与一致性终极指南
数据库·redis·缓存
念何架构之路5 小时前
存储技术Redis
数据库·redis·缓存
淘源码d5 小时前
医院专业级PACS系统完整源码(C+VC+MSSQL)
c语言·数据库·sqlserver·源码·pacs系统·医学影像系统
wu8587734576 小时前
向量数据库不是银弹:从枚举漏检到 ReACT 多轮召回的实践路径
前端·数据库·react.js