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 等

相关推荐
TDengine (老段)1 小时前
TDengine RPC 通信层深度解析 — 协议格式、连接管理与重试机制
大数据·数据库·rpc·架构·时序数据库·tdengine·涛思数据
KaMeidebaby1 小时前
卡梅德生物技术快报|噬菌体筛选全流程技术方案:弧菌抑菌菌株筛选、特性鉴定与效果测试
前端·数据库·其他·百度·新浪微博
蜀道山老天师1 小时前
从零搭建 Prometheus 监控 MySQL:含二进制安装、授权、exporter 配置全流程
运维·数据库·mysql·adb·云原生·prometheus
yubin12855709231 小时前
mysql正则函数REGEXP
android·数据库·mysql
塔能物联运维1 小时前
存量机房低成本改造:塔能两相液冷实现投入与效益双赢
大数据·数据库·人工智能
2401_850491651 小时前
PHP 中处理会话数组时的类型错误解析与修复指南
jvm·数据库·python
ㄟ留恋さ寂寞1 小时前
如何修改数据库实例名_ORACLE_SID环境变量重命名实战
jvm·数据库·python
专注API从业者1 小时前
Open Claw 实战:用淘宝商品 API 实现自动化监控选品系统
大数据·运维·数据库·自动化
2401_850491651 小时前
使用 curl 调用 Go 标准库 RPC 服务(JSON-RPC 协议详解)
jvm·数据库·python