深入浅出MySQL——MySQL基础

news2024/9/22 1:51:13

文章目录

  • 数据库基础
    • 数据库概念
    • 主流数据库
    • 服务器,数据库,表关系
    • 基本使用
    • MySQL架构
    • SQL语句分类
    • 存储引擎
  • 库的操作
    • 创建数据库
    • 创建数据库案例
    • 字符集和校验规则
    • 操纵数据库
  • 表的操作
    • 创建表
    • 查看表结构
    • 修改表
    • 删除表
  • 数据类型
    • 数据类型分类
    • 数值类型
    • 字符串类型
  • 表的约束
    • 空属性
    • 默认值
    • 列描述
    • zerofil
    • 主键
    • 复合主键
    • 自增长
    • 唯一键
    • 外键

数据库基础

数据库概念

   存储数据用文件就可以实现,但是使用文件存储数据具有如下的缺点:1.文件的安全性问题,2.文件不利于数据查询和管理,3.文件不利于存储海量数据,4.文件在程序中控制不方便。为了解决上述问题,专家们设计出更加利于管理数据的东西——数据库,它能更有效的管理数据。数据库的水平是衡量一个程序员水平的重要指标。

   数据库是数据库专家统一编写的数据库服务,该服务以mysqld的形式呈现,在磁盘上有大量的文件保存数据库和数据库内部的数据,把数据库服务端和数据库及其内部的数据统称为数据库。 从狭义上来讲,数据库是以特定的格式保存好的文件,从广义上来讲,数据库是提供较为便捷的数据的存取服务的软件集合或解决方案。

   数据库的存储介质是磁盘和内存,但是主要是磁盘为主,内存为辅。mysql也是一种文件系统,重点是针对文件内容


主流数据库

  • SQL Sever: 微软的产品,.Net程序员的最爱,中大型项目。
  • Oracle: 甲骨文产品,适合大型项目,复杂的业务逻辑,并发一般来说不如MySQL。
  • MySQL:世界上最受欢迎的数据库,属于甲骨文,并发性好,不适合做复杂的业务。主要用在电商,SNS,论坛。对简单的SQL处理效果好。
  • PostgreSQL :加州大学伯克利分校计算机系开发的关系型数据库,不管是私用,商用,还是学术研究使用,可以免费使用,修改和分发。
  • SQLite: 是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。
  • H2: 是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接嵌入到应用项目中。

服务器,数据库,表关系

   所谓安装数据库服务器,只是在机器上安装了一个数据库管理系统程序,这个管理程序可以管理多个数据库,一般开发人员会针对每一个应用创建一个数据库。为保存应用中实体的数据,一般会在数据库中创建多个表,以保存程序中实体的数据。

数据库服务器、数据库和表的关系如下:
在这里插入图片描述
(DB———Database)


基本使用

连接数据库

mysql -h 127.0.0.1 -P 3306 -u root -p

   如果没有写 -h 127.0.0.1 默认是连接本地,如果没有写 -P 3306 默认是连接3306端口号。

创建数据库

create database helloworld;

使用数据库

use helloworld;

创建数据库表

create table student(
	id int,
	name varchar(32),
	gender varchar(2)
);

表中插入数据

insert into student (id, name, gender) values (1, '张三', '男');
insert into student (id, name, gender) values (2, '李四', '女');
insert into student (id, name, gender) values (3, '王五', '男');

查询表中的数据

select * from student;

数据逻辑存储
在这里插入图片描述


MySQL架构

   MySQL 是一个可移植的数据库,几乎能在当前所有的操作系统上运行,如 Unix/Linux、Windows、Mac 和 Solaris。各种系统在底层实现方面各有不同,但是 MySQL 基本上能保证在各个平台上的物理体系结构的一致性。
在这里插入图片描述


SQL语句分类

  • DDL【data definition language】 数据定义语言,用来维护存储数据的结构,对数据库和表结构,更多是属性操作。代表指令: create, drop, alter
  • DML【data manipulation language】 数据操纵语言,用来对数据进行操作,对数据库和表结构,更多的是数据内容操作。代表指令: insert,delete,update。DML中又单独分了一个DQL,数据查询语言,代表指令: select
  • DCL【Data Control Language】 数据控制语言,主要负责权限管理和事务,操作整个MySQL的系统安全和账户管理工作。代表指令: grant,revoke,commit

存储引擎

   存储引擎是数据库管理系统如何存储数据、如何为存储的数据建立索引和如何更新、查询数据等技术的实现方法。MySQL的核心就是插件式存储引擎,支持多种存储引擎。

查看存储引擎

show engines;

存储引擎对比
在这里插入图片描述


库的操作

创建数据库

语法:

CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,
create_specification] ...]

create_specification:
	[DEFAULT] CHARACTER SET charset_name
	[DEFAULT] COLLATE collation_name
  • 大写的表示关键字
  • [] 是可选项
  • CHARACTER SET: 指定数据库采用的字符集
  • COLLATE: 指定数据库字符集的校验规则

创建一个数据库在Linux机器本质上是在做什么?

  在mysql中建立一个数据库,create database本质上是在Linux机器下建立了一个目录。


创建数据库案例

创建名为 db1 的数据库

create database db1;

   创建数据库没有指定字符集和校验规则时,系统使用默认字符集:utf8,校验规则是:utf8_ general_ ci


创建一个使用utf8字符集的 db2 数据库

create database db2 charset=utf8;

创建一个使用utf字符集,并带校对规则的 db3 数据库

create database db3 charset=utf8 collate utf8_general_ci;

字符集和校验规则

  MySQL数据库的核心工作不外乎存数据和取数据,字符集保证按照特定的编码来存储数据,数据的校验编码用来取数据进行比较。一般字符集和检验规则(集)是匹配的。设置数据库的编码和校验规则, 其实是影响数据库的内部的表所对应的编码和校验规则。


查看系统默认字符集以及校验规则

show variables like 'character_set_database';
show variables like 'collation_database';

查看数据库支持的字符集

show charset;

查看数据库支持的字符集校验规则

show collation;

校验规则对数据库的影响

  创建一个数据库test1,校验规则使用utf8_ general_ ci[不区分大小写];再创建一个数据库test2,校验规则使用utf8_ bin[区分大小写]。插入相同的数据 ‘a’ ,‘A’,‘b’,‘B’,进行查询,结果完全不同。

mysql> use test1;
mysql> select * from person where name='a';
+------+
| name |
+------+
| a |
| A |
+------+
2 rows in set (0.01 sec)
mysql> use test2;
mysql> select * from person where name='a';
+------+
| name |
+------+
| a |
+------+
2 rows in set (0.01 sec)

操纵数据库

查看数据库

show databases;

显示创建语句

show create database 数据库名;
mysql> show create database mytest;
+----------+----------------------------------------------------------------+
| Database | Create Database |
+----------+----------------------------------------------------------------+
| mysql | CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTER SET utf8 */ |
+----------+----------------------------------------------------------------+
  • MySQL 建议我们关键字使用大写,但是不是必须的。
  • 数据库名字的反引号``,是为了防止使用的数据库名刚好是关键字
  • /*!40100 default… */ 这个不是注释,表示当前mysql版本大于4.01版本,就执行这句话。

修改数据库

ALTER DATABASE db_name
[alter_spacification [,alter_spacification]...]

alter_spacification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name

  对数据库的修改主要指的是修改数据库的字符集,校验规则。例如将 mytest 数据库字符集改成 gbk。MySQL不支持库名字的修改,但可以修改表名。

mysql> alter database mytest charset = gbk;
Query OK, 1 row affected (0.00 sec)
mysql> show create database mytest;
+----------+----------------------------------------------------------------+
| Database | Create Database |
+----------+----------------------------------------------------------------+
| mytest | CREATE DATABASE `mytest` /*!40100 DEFAULT CHARACTER SET gbk */ |
+----------+----------------------------------------------------------------+

数据库删除

DROP DATABASE [IF EXISTS] db_ name;

  删除数据后,对应的数据库文件夹被删除,级联删除,里面的数据表全部被删,所以不要随意删除数据库


数据库备份

  数据库备份有两种方案,一种是对数据内容做备份,另外一种是对操作语句做备份,mysqldump 是对于操作语句做备份。

操作:

退出连接数据库后在命令行中输入

mysqldump -P3306 -u root -p 密码 -B 数据库名 > 数据库备份存储的文件路径

如果备份的是其中的一张表

mysqldump -u root -p 数据库名 表名1 表名2 > D:/mytest.sql

备份多个数据库

mysqldump -u root -p -B 数据库名1 数据库名2 ... > 数据库存放路径

  如果备份一个数据库时,没有带上-B参数, 在恢复数据库时,需要先创建空数据库,然后使用数据库,再使用source来还原。

示例:将mytest库备份到文件

mysqldump -P3306 -u root -p123456 -B mytest > D:/mytest.sql

  打开看看 mytest.sql 文件里的内容,其实把整个创建数据库,建表,导入数据的语句都装载这个文件中。


数据库还原

mysql > source D:/mysql-5.7.22/mytest.sql;

查看连接情况

show processlist

  该语句可以告诉我们当前有哪些用户连接到我们的MySQL,如果查出某个用户不是你正常登陆的,很有可能你的数据库被人入侵了。当发现自己数据库比较慢时,可以用这个指令来查看数据库连接情况。

示例:

mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+------+---------+------+-------+------------------+
| 2 | root | localhost | test | Sleep | 1386 | | NULL |
| 3 | root | localhost | NULL | Query | 0 | NULL | show processlist |
+----+------+-----------+------+---------+------+-------+------------------+

表的操作

创建表

语法:

CREATE TABLE table_name (
	field1 datatype,
	field2 datatype,
	field3 datatype
) character set 字符集 collate 校验规则 engine 存储引擎;

说明:

  • field 表示列名
  • datatype 表示列的类型
  • character set 字符集,如果没有指定字符集,则以所在数据库的字符集为准。
  • collate 校验规则,如果没有指定校验规则,则以所在数据库的校验规则为准。

创建表在Linux机器下是在做什么?

  在mysql中,建立一个表本质上实在Linux机器下创建对应的文件。


创建表案例

create table users (
	id int,
	name varchar(20) comment '用户名',
	password char(32) comment '密码是32位的md5值',
	birthday date comment '生日'
) character set utf8 engine MyISAM;

  不同的存储引擎,创建表的文件不一样。users 表存储引擎是 MyISAM ,在数据目中有三个不同的文件,分别是:users.frm:表结构;users.MYD:表数据;users.MYI:表索引。

在这里插入图片描述


查看表结构

desc 表名;

在这里插入图片描述


修改表

  在项目实际开发中,经常修改某个表的结构,比如字段名字,字段大小,字段类型,表的字符集类型,表的存储引擎等等。还有需求,添加字段,删除字段等等,这时就需要修改表。

ALTER TABLE tablename ADD (column datatype [DEFAULT expr][,column
datatype]...);

ALTER TABLE tablename MODIfy (column datatype [DEFAULT expr][,column datatype]...);

ALTER TABLE tablename DROP (column);
  • 案例:在users表添加二条记录
mysql> insert into users values(1,'a','b','1982-01-04'),(2,'b','c','1984-01-04');
  • 案例:在users表添加一个字段,用于保存图片路径。(插入新字段后,对原来表中的数据没有影响,原来的数据仍然存在)
mysql> alter table users add assets varchar(100) comment '图片路径' after birthday;

  • 案例:修改name,将其长度改成60
mysql> alter table users modify name varchar(60);
  • 案例:删除password列(删除字段一定要小心,删除字段及其对应的列数据都没了)
mysql> alter table users drop password;

在这里插入图片描述

  • 案例:修改表名为employee
mysql> alter table users rename to employee;//(to可以省掉)

在这里插入图片描述

  • 案例:将name列修改为xingming。change 修改列名;rename 修改表名
mysql> alter table employee change name xingming varchar(60); --新字段需要完整定义

删除表

语法:

DROP TABLE [IF EXISTS] tbl_name [, tbl_name] ...

示例:

mysql> drop table t1;

数据类型

数据类型分类

在这里插入图片描述


数值类型

在这里插入图片描述


tinyint类型

mysql> create table tt1(num tinyint);
mysql> insert into  tt1 values(128); -- 越界插入,报错

  在MySQL中,整型可以指定是有符号的和无符号的,默认是有符号的,可以通过UNSIGNED来说明某个字段是无符号的。

mysql> create table tt2(num tinyint unsigned);
mysql> insert into tt2 values(-1); -- 无符号,范围是: 0 ~ 255

bit类型

语法:

bit[(M)] : 位字段类型。M表示每个值的位数,范围从164。如果M被忽略,默认为1

举例:

mysql> create table tt4 ( id int, a bit(8));
mysql> insert into tt4 values(10, 10);
mysql> select * from tt4; #发现很怪异的现象,a的数据10没有出现
+------+------+
| id | a |
+------+------+
| 10 |   |
+------+------+

  上述案例发现很怪异的现象,a的数据10没有出现,这是因为bit字段在显示时,是按照ASCII码对应的值显示。10表示的是换行符,当然不会显示。

建议:

  有这样的值,只存放0或1,这时可以定义bit(1)。这样可以节省空间。

mysql> create table tt5(gender bit(1));
mysql> insert into tt5 values(0);
mysql> insert into tt5 values(1);
mysql> insert into tt5 values(2); -- 当插入2时,已经越界了
ERROR 1406 (22001): Data too long for column 'gender' at row 1

float

语法:

float[(m, d)] [unsigned] : M指定显示长度,d指定小数位数,占用空间4个字节

案例:

mysql> create table tt6(id int, salary float(4,2));
mysql> insert into tt6 values(100, -99.99);
mysql> insert into tt6 values(101, -99.991); #多的这一点被拿掉了
mysql> select * from tt6;
+------+--------+
| id | salary |
+------+--------+
| 100 | -99.99 |
| 101 | -99.99 |
+------+--------+
2 rows in set (0.00 sec)

  小数 float(4,2)表示的范围是-99.99 ~ 99.99,MySQL在保存值时会进行四舍。如果定义的是float(4,2) unsigned 这时,因为把它指定为无符号的数,范围是0 ~ 99.99。


decimal

语法:

decimal(m, d) [unsigned] : 定点数m指定长度,d表示小数点的位数
  • decimal(5,2) 表示的范围是 -999.99 ~ 999.99
  • decimal(5,2) unsigned 表示的范围 0 ~ 999.99
  • decimal和float很像,但是有区别:float和decimal表示的精度不一样,float表示的精度大约是7位,decimal整数最大位数m为65。支持小数最大位数d是30。如果d被省略,默认为0.如果m被省略,默认是10。如果希望小数的精度高,推荐使用decimal。
mysql> create table tt8 ( 
		id int, 
		salary float(10,8), 
		salary2 decimal(10,8)
		);
mysql> insert into tt8 values(100,23.12345612, 23.12345612);
mysql> select * from tt8;
+------+-------------+-------------+
| id  | salary 		| salary2 |
+------+-------------+-------------+
| 100 | 23.12345695 | 23.12345612 | 
+------+-------------+-------------+

字符串类型

char

语法:

char(L): 固定长度字符串,L是可以存储的长度,单位为字符,最大长度值可以为255

案例:

mysql> create table tt9(id int, name char(2));
mysql> insert into tt9 values(100, 'ab');
mysql> insert into tt9 values(101, '中国');
mysql> select * from tt9;
+------+--------+
| id  | name |
+------+--------+
| 100 | ab   |
| 101 | 中国  |
+------+--------+

说明:

  char(2) 表示可以存放两个字符,可以是字母或汉字,但是不能超过2个,最多只能是255。mysql中的字符,说的就是一个字符,可以是abcd中任意一个字符或1234中任意一个字符,也可以是一个汉字。


varchar

语法:

varchar(L): 可变长度字符串,L表示字符长度,最大长度65535个字节

案例:

mysql> create table tt10(id int ,name varchar(6)); --表示这里可以存放6个字符
mysql> insert into tt10 values(100, 'hello');
mysql> insert into tt10 values(100, '我爱你,中国');
mysql> select * from tt10;
+------+--------------------+
| id 	| name 		 |
+------+--------------------+
| 100 	| hello 	 |
| 100 	| 我爱你,中国 |
+------+--------------------+

说明:

  • 关于varchar(len),len到底是多大,这个len值,和表的编码密切相关
  • 一个字符串的长度有上限和它是变长的并不直接冲突。
  • varchar长度可以指定为0到65535之间的值,但是有1 - 3 个字节用于记录数据大小,所以说有效字节数是65532。
  • 当表的编码是utf8时,varchar(n)的参数n最大值是65532/3=21844[因为utf8中,一个字符占用3个字节,如果编码是gbk,varchar(n)的参数n最大65532/2=32766,因为gbk中,一个字符占用2字节

char和varchar比较

在这里插入图片描述


如何选择定长或变长字符串?

  • 如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,md5。
  • 如果数据长度有变化,就使用变长(varchar), 比如:名字,地址,但是你要保证最长的能存的进去。
  • 定长的磁盘空间比较浪费,但是效率高
  • 变长的磁盘空间比较节省,但是效率低
  • 定长的意义是,直接开辟好对应的空间。
  • 变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。

日期和时间类型

常用的日期有如下三个:

  • date :日期 'yyyy-mm-dd' ,占用三字节
  • datetime 时间日期格式 'yyyy-mm-dd HH:ii:ss' 表示范围从 1000 到 9999 ,占用八字节
  • timestamp :时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节

案例:

//创建表
mysql> create table birthday (t1 date, t2 datetime, t3 timestamp);
//插入数据  添加数据时,时间戳自动补上当前时间
mysql> insert into birthday(t1,t2) values('1997-7-1','2008-8-8 12:1:1'); --插入两种时间
mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 1997-07-01 | 2008-08-08 12:01:01 | 2017-11-12 18:28:55 | 
+------------+---------------------+---------------------+
//更新数据, 时间戳会更新成当前时间
mysql> update birthday set t1='2000-1-1';
mysql> select * from birthday;
+------------+---------------------+---------------------+
| t1 | t2 | t3 |
+------------+---------------------+---------------------+
| 2000-01-01 | 2008-08-08 12:01:01 | 2017-11-12 18:32:09 |
+------------+---------------------+---------------------+

enum和set

语法:

enum:枚举,“单选” 类型;
enum('选项1','选项2','选项3',...);

  该设定只是提供了若干个选项的值,最终一个单元格中,实际只存储了其中一个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,3,…最多65535个;当我们添加枚举值时,也可以添加对应的数字编号。

set:集合,“多选”类型;
set('选项值1','选项值2','选项值3', ...);

  该设定只是提供了若干个选项的值,最终一个单元格中,设计可存储了其中任意多个值;而且出于效率考虑,这些值实际存储的是“数字”,因为这些选项的每个选项值依次对应如下数字:1,2,4,8,16,32,…最多64个。但是不建议在添加枚举值,集合值的时候采用数字的方式,因为不利于阅读。

案例:

  有一个调查表votes,需要调查人的喜好, 比如(登山,游泳,篮球,武术)中去选择[可以多选],(男,女)[单选]。

mysql> create table votes(
	-> username varchar(30),
	-> hobby set('登山','游泳','篮球','武术'), 
	-> gender enum('男','女'));
mysql>insert into votes values('雷锋', '登山,武术', '男');
mysql>insert into votes values('Juse','登山,武术',2);
mysql>select * from votes where gender=2; 
+----------+---------------+--------+
| username | hobby 	  | gender |
+----------+---------------+--------+
| Juse 	   | 登山,武术 ||
+----------+---------------+--------+

集合查询使用 find_ in_ set 函数:

find_in_set(sub,str_list) :如果 sub 在 str_list 中,则返回下标;如果不在,返回0;str_list 用逗号分隔的字符串。
  • 案例:查询爱好登山的人
mysql> select * from votes where find_in_set('登山', hobby);
+----------+---------------+--------+
| username | hobby      | gender |
+----------+---------------+--------+
| 雷锋 	   | 登山,武术   ||
| Juse 	   | 登山,武术   ||
| LiLei    | 登山        ||
+----------+---------------+--------+

表的约束

  数据类型可以约束数据,但是数据类型约束很单一,需要有一些额外的约束,更好的保证数据的合法性,从业务逻辑角度保证数据的正确性。


空属性

  有两个值:null(默认的)和not null(不为空)。数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。NULL和空的区别:NULL代表的是没有,空代表的是有,但是是空串。

  • 案例:创建一个班级表,包含班级名和班级所在的教室。

  站在正常的业务逻辑中:如果班级没有名字,你不知道你在哪个班级,如果教室名字可以为空,就不知道在哪上课。所以我们在设计数据库表的时候,一定要在表中进行限制,满足上面条件的数据就不能插入到表中。这就是“约束”。

mysql> create table myclass(
	-> class_name varchar(20) not null,
	-> class_room varchar(10) not null);
mysql> desc myclass;
+------------+-------------+------+-----+---------+-------+
| Field 	 | Type        | Null | Key  | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| class_name | varchar(20) | NO   |      | NULL    |  |
| class_room | varchar(10) | NO   |      | NULL    |  |
+------------+-------------+------+-----+---------+-------+
//插入数据时,没有给教室数据插入失败:
mysql> insert into myclass(class_name) values('class1');
ERROR 1364 (HY000): Field 'class_room' doesn't have a default value

默认值

  默认值是某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值。not null和defalut一般不需要同时出现,因为default本身有默认值,不会为空。default的约束其实降低了,但是可以保证表中数据的完整性。default 表示当用户不显示的向指定列中插入,default会自动起效果

mysql> create table tt10 (
	-> name varchar(20) not null,
	-> age tinyint unsigned default 0,
	-> sex char(2) default '男'
	-> );
mysql> desc tt10;
+-------+---------------------+------+-----+---------+-------+
| Field | Type           		| Null | Key | Default | Extra|
+-------+---------------------+------+-----+---------+-------+
| name  | varchar(20)    		| NO   |     |   NULL  | 	  |
| age   | tinyint(3) unsigned   | YES  |     |    0    |      |
| sex   | char(2)        		| YES  |     ||       |
+-------+---------------------+------+-----+---------+-------+

  当数据在插入的时候不给该字段赋值,就使用默认值。只有设置了default的列,才可以在插入值的时候,对列进行省略。

mysql> insert into tt10(name) values('zhangsan');
mysql> select * from tt10;
+----------+------+------+
| name 		| age | sex |
+----------+------+------+
| zhangsan  | 0   ||
+----------+------+------+

列描述

  列描述:comment,没有实际含义,专门用来描述字段,会根据表创建语句保存,用来给程序员或DBA来进行了解。

mysql> create table tt12 (
	-> name varchar(20) not null comment '姓名',
	-> age tinyint unsigned default 0 comment '年龄',
	-> sex char(2) default '男' comment '性别'
	-> );

通过desc查看不到注释信息,通过show可以看到:

mysql> show create table tt12\G
*************************** 1. row ***************************
	Table: tt12
Create Table: CREATE TABLE `tt12` (
	`name` varchar(20) NOT NULL COMMENT '姓名',
	`age` tinyint(3) unsigned DEFAULT '0' COMMENT '年龄',
	`sex` char(2) DEFAULT '男' COMMENT '性别'
) ENGINE=MyISAM DEFAULT CHARSET=gbk
1 row in set (0.00 sec)

zerofil

mysql> show create table tt3\G
	***************** 1. row *****************
	Table: tt3
	Create Table: CREATE TABLE `tt3` (
	`a` int(5) unsigned zerofill DEFAULT NULL,
	`b` int(10) unsigned DEFAULT NULL
	) ENGINE=MyISAM DEFAULT CHARSET=gbk
	1 row in set (0.00 sec)

  show看看tt3表的建表语句,可以看到int(5),这个代表什么意思呢?整型不是4字节码?这个5又代表什么呢?当在tt3中插入(1,2),再看结果。

mysql> select * from tt3;
+-------+------+
| a 	| b |
+-------+------+
| 00001 | 2 |
+-------+------+

  可以看到a的值由原来的1变成00001,这就是zerofill属性的作用,如果宽度小于设定的宽度(这里设置的是5),自动填充0。如果没有zerofill这个属性,括号内的数字是毫无意义的要注意的是,这只是最后显示的结果,在MySQL中实际存储的还是1,00001只是设置了zerofill属性后的一种格式化输出而已。


主键

  primary key用来唯一的约束该字段里面的数据,不能重复,不能为空一张表中最多只能有一个主键;主键所在的列通常是整数类型。结合你的业务,可以选择一个唯一的列属性作为主键。并且选择与业务无关的唯一值。这样设计,主键值与业务无关,业务调整就不会影响整体主键的表结构。

  • 案例:创建表的时候直接在字段上指定主键
mysql> create table tt13 (
	-> id int unsigned primary key comment '学号不能为空',
	-> name varchar(20) not null);
mysql> desc tt13;
+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | NO | PRI | NULL | |
| name  | varchar(20)      | NO |  	  | NULL | |
+-------+------------------+------+-----+---------+-------+
  • 案例:主键对应的字段中不能重复,一旦主键重复,操作失败
mysql> insert into tt13 values(1, 'aaa');
mysql> insert into tt13 values(1, 'aaa');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
  • 案例:当表创建好以后但是没有主键的时候,可以再次追加主键
alter table 表名 add primary key(字段列表)
  • 案例:删除主键
alter table 表名 drop primary key;
mysql> alter table tt13 drop primary key;

复合主键

  在创建表的时候,在所有字段之后,使用primary key来创建主键,如果有多个字段作为主键,可以使用复合主键。

mysql> create table tt14(
	-> id int unsigned,
	-> course char(10) comment '课程代码',
	-> score tinyint unsigned default 60 comment '成绩',
	-> primary key(id, course) -- id和course为复合主键
	-> );
mysql> desc tt14;
+--------+---------------------+------+-----+---------+-------+
| Field | Type 				  | Null | Key | Default | Extra |
+--------+---------------------+------+-----+---------+-------+
| id 	| int(10) unsigned    | NO   | PRI |   0  	 |  	 | 
| course| char(10) 			  | NO   | PRI |    	 | 		 |
| score | tinyint(3) unsigned | YES  |     |   60 	 |       |
+--------+---------------------+------+-----+---------+-------+

mysql> insert into tt14 (id,course)values(1, '123');
Query OK, 1 row affected (0.02 sec)
mysql> insert into tt14 (id,course)values(1, '123');
ERROR 1062 (23000): Duplicate entry '1-123' for key 'PRIMARY' -- 主键冲突

自增长

  auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。

  自增长的特点 : 1.设定为自增长,一定是主键。2.自增长字段必须是整数。3.一张表最多只能有一个自增长。

mysql> create table tt21(
	-> id int unsigned primary key auto_increment,
	-> name varchar(10) not null default ''
	-> );
mysql> insert into tt21(name) values('a');
mysql> insert into tt21(name) values('b');
mysql> select * from tt21;
+----+------+
| id | name |
+----+------+
| 1  | 	a   |
| 2  |  b   |
+----+------+

  在插入后获取上次插入的 AUTO_INCREMENT 的值,批量插入获取的是第一个值。

mysql > select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 		 1         |
+------------------+

索引

  在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。索引的作用相当于图书的目录,可以根据目录中的页码快速找到所需的内容。

  索引提供指向存储在表的指定列中的数据值的指针,然后根据您指定的排序顺序对这些指针排序。数据库使用索引以找到特定值,然后顺指针找到包含该值的行。这样可以使对应于表的SQL语句执行得更快,可快速访问数据库表中的特定信息。


唯一键

  一张表中有往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键,唯一键就可以解决表中有多个字段需要唯一性约束的问题。**唯一键和主键并不冲突,反而是相互补充的,用来共同维护表的完整性。**主键只是众多具有唯一性的属性列中被选择成为主键而已,其他字段的唯一性,在建表的时候也需要保证,但是主键只能有一个,所以MySQL提供了另一种保证数据列信息唯一性的方案——唯一键。

  关于唯一键和主键的区别,可以简单理解成 主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。 主键更多的是为了保证我们在查找的时候,找到唯一的一条记录。唯一键更多的是为了保证在表中,各个不同的值,一定要在mysql层面保证该值的唯一性。unique 作用的字段允许为NULL,而primary key的字段不允许为NULL;并且一张表中最多只能有一个主键,而唯一键可以有多个。

mysql> create table student (
		-> id char(10) unique comment '学号,不能重复,但可以为空',
		-> name varchar(10)
		-> );
mysql> insert into student(id, name) values('01', 'aaa');
mysql> insert into student(id, name) values('01', 'bbb'); --唯一约束不能重复
ERROR 1062 (23000): Duplicate entry '01' for key 'id'
mysql> insert into student(id, name) values(null, 'bbb'); -- 但可以为空
mysql> select * from student;
+------+------+
| id   | name |
+------+------+
| 01   | aaa  |
| NULL | bbb  |
+------+------+

外键

  MySQL属于关系型数据库,在表和表之间也一定会产生某种关系。外键用于定义主表和从表之间的关系,维护主表和从表之间的约束。外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。

语法:

foreign key (字段名) references 主表()

案例:

在这里插入图片描述
先创建主键表

create table myclass (
	id int primary key,
	name varchar(30) not null comment'班级名'
);

再创建从表

create table stu (
	id int primary key,
	name varchar(30) not null comment '学生名',
	class_id int,
	foreign key (class_id) references myclass(id)
);

正常插入数据

mysql> insert into myclass values(10, 'C++大牛班'),(20, 'java大神班');
mysql> insert into stu values(100, '张三', 10),(101, '李四',20);

插入一个班级号为30的学生,因为没有这个班级,所以插入不成功

mysql> insert into stu values(102, 'wangwu',30);
ERROR 1452 (23000): Cannot add or update a child row:a foreign key constraint fails (mytest.stu, CONSTRAINT stu_ibfk_1 FOREIGN KEY (class_id) REFERENCES myclass (id))

插入班级id为null,比如来了一个学生,目前还没有分配班级

mysql> insert into stu values(102, 'wangwu', null);

理解外键约束

  首先这个世界是数据很多都是相关性的。理论上,上面的例子,我们不创建外键约束,就正常建立学生表,以及班级表,该有的字段我们都有。此时,在实际使用的时候,可能会出现什么问题?有没有可能插入的学生信息中有具体的班级,但是该班级却没有在班级表中。因为此时两张表在业务上是有相关性的,但是在业务上没有建立约束关系,那么就可能出现问题。解决方案就是通过外键完成的。建立外键的本质其实就是把相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,mysql不允许你插入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/456526.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【华为机考】专题突破 第一周:单调栈 739 、503 、901、84

刷题顺序参考于 《2023华为机考刷题指南:八周机考速通车》 前言 单调栈:分为单调递增和单调递减栈。(栈内元素成递增或者递减性): 单调递增栈:从栈底到栈顶数据是从大到小,即 栈内的元素从栈顶 到栈底 是递增的&#x…

react-10 函数式写法rsc,配合HOOKS钩子函数

性能优化:useMemo :用于组件性能优化(缓存计算属性,变化才执行)是通过缓存值的方式实现性能优化 useMemo(callback, array):性能优化,利用了闭包的特性,会返回一个记忆值, 通过 记…

3D线光谱共焦位移传感器在医疗领域的应用

随着社会的发展,越来越多的行业对微观物体表面形貌的观察提出了越来越高的要求。与生命健康息息相关的医疗行业就是其中之一。但是传统的显微镜只能达到聚焦区域的图像清晰,非聚焦区域图像模糊。因此,普通显微镜无法在相同景深下实现对物体表…

两大消息爆出,币圈正在响应全球“去美元化”行动

为了维持美元霸权、对全球进行收割,美联储连续加息反而拉爆了自家银行。欧美银行危机事件,让人们觉得把钱放在银行里并不安全,加密货币的去中心化本质,令币圈逆风翻盘。数据显示,比特币今年上涨了近72%,这可…

《编码——隐藏在计算机软硬件背后的语言》精炼——第12章(二进制加法器)

“I hear and I forget. I see and I remember. I do and I understand”——Confucius 人类计算二进制数的方法 我们先计算本位的结果,称为加法位;再计算是否进位,称为进位位。 搭建二进制加法器 我们用逻辑门来搭建二进制加法器。它的思想…

CHAPTER 8: 《DESIGN A URL SHORTENER》第8章 《设计一个url伸缩器》

CHAPTER 8: DESIGN A URL SHORTENER 在这一章中,我们将解决一个有趣而经典的系统设计面试问题:设计一个像tinyurl这样的网址缩短服务。 步骤1 -理解问题并确定设计范围 系统设计面试的问题是故意留下开放式的。精心设计系统中,提出澄清性问题是至关重…

HDCTF 2023 复盘

web yamiyami 当时考虑直接读的/proc/self/environ 读到flag是not_flag 就没考虑过/proc/1/environ了 然后不知道py3URL二次编码的特性,读不到源码,无从下手 做flask算pin码的题做多了,还以为pid是1的就是self,难顶 上面那种是非预期 预期是yaml反序列化 先读源码 /read?u…

产品推荐丨智慧水利行业应用终端+云平台

智慧水利是我国智慧城市建设的重要延伸,是新时代水利现代化的战略目标,贯穿于防汛抗旱减灾、水资源合理配置和高效利用、水资源和河湖健康保障等体系。随着水利技术的集成发展与场景的成熟应用,我国水利现已完成从自动化阶段到信息化阶段的过…

学习系统编程No.13【文件系统】

引言: 北京时间:2023/3/31/7:48,该篇博客在两天前本就应该产出,但是摆烂谁拦得住,所以呜呜呜!本以为欠的钱也要快还完了,没想到啊,越欠越多,烦人!但是&#…

领略未来无需远方,华为全屋智能将在AWE描绘智慧生活新图景

作者 | 曾响铃 文 | 响铃说 4月27日-30日,AWE 2023中国家电及消费电子博览会将在上海新国际博览中心举行,这是AWE展沉淀两年后的再次回归。 作为家电及消费电子领域TOP3的国际盛会,本届AWE以“智科技,创未来”为主题&#xff0…

Redis 数据存储原理

核心模块如图 1-10。 图1-10 图 1-10 Client 客户端,官方提供了 C 语言开发的客户端,可以发送命令,性能分析和测试等。 网络层事件驱动模型,基于 I/O 多路复用,封装了一个短小精悍的高性能 ae 库,全称是 …

如何写好学位论文

昨天刚提交了学位论文,今天准备来总结一下一些常用的Word写作技巧。 样式与多级列表 论文一般都会对章节条目的标题、参考文献、表格内容、题注的字体字号、行间距、段落间距等作出规定。为每一类文字设置一种样式,在写的时候直接应用样式可以方便地对全…

研报精选230421

目录 【行业230421南京证券】氢能行业:地缘政治加速绿色能源转型 【行业230421华安证券】AIGC行业研究框架与投资逻辑 【行业230421信达证券】工控行业深度报告:行业拐点将至,国产品牌加速崛起 【个股230421国信证券_华阳集团】聚焦汽车智能化…

ruoyi启动前端报错‘vue-cli-service‘ 不是内部或外部命令

解决方案: 在新项目的pack.json的文件目录,执行命令npm install 或者 cnpm install 如果报npm 不是内部命令,需要在系统配置全局的变量 在使用npm的时候,或者是通过npm下载了一些包,使用这些包的时候,有时…

LightGBM模型详解

1.背景 LightGBM 是微软开发的 boosting 集成模型,和 XGBoost 一样是对 GBDT 的优化和高效实现,原理有一些相似之处,但它很多方面比 XGBoost 有着更为优秀的表现。官方给出的这个工具库模型的优势如下: 更快的训练效率低内存使用…

全网最详细,web自动化测试窗口框架与验证码登录处理(超详细实战)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 selenium的作用域…

传输协议特点大比拼之TCP

文章目录 前言一.Tpc报头格式源端口和目的端口:序列号:确认号:数据偏移:控制位:窗口大小:校验和:紧急指针: 二.TPC原理2.1 确认应答机制2.2 超时重传机制2.3 连接管理机制2.3.1 三次…

档案室温湿度相关资料

国家档案局《档案库房技术管理暂行规定》对档案库房(也适用于机关档案室)温湿度要求做了如下明确界定:档案库房(含胶片室、磁带室)的温度应控制在14~24℃,有设备的库房日变化幅度不超过2℃,相对湿度应控制在45~60%&…

【大数据离线开发】9 Pig:数据分析引擎

文章目录 Pig:数据分析引擎9.1 什么是Pig9.1.1 简介9.1.2 与 Hive 的对比 9.2 Pig的体系结构和数据模型9.3 Pig的安装和工作模式9.3.1 Pig安装9.3.2 Pig工作模式 9.4 Pig的内置函数9.5 使用PigLatin语句分析数据9.6 Pig的自定义函数9.6.1 自定义过滤和运算函数9.6.2…

低资源环境下对风湿性心脏病的综合预测

文章目录 Ensembled Prediction of Rheumatic Heart Disease from Ungated Doppler Echocardiography Acquired in Low-Resource Settings摘要方法Echocardiogram Homogenization风湿性心脏病的检测 Ensembled Prediction of Rheumatic Heart Disease from Ungated Doppler Ech…