MySQL 基础 (二)- 表操作----day03

1. MySQL表数据类型

MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

1.1 数值数据类型

1.1.1 整数类型

类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 字节 (-128,127) (0,255) 小整数值
SMALLINT 2 字节 (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 字节 (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值

INTEGER同INT。

1.1.2 浮点数类型与定点数类型

类型 大小 范围(有符号) 范围(无符号) 用途
FLOAT 4 字节 (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度
浮点数值
DOUBLE 8 字节 (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度
浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值

小数值

定点数


DECIMAL(18,9):表示该字段可存储数字最大的长度是18位,其中小数位最大的长度是9位。由于DECIMAL每4个字节存9个数字,小数点占一个字节,所以该字段占9个字节。

1.2 字符串类型

类型 大小 用途
CHAR 0-255字节 定长字符串
VARCHAR 0-65535 字节 变长字符串
TINYBLOB 0-255字节 不超过 255 个字符的二进制字符串
TINYTEXT 0-255字节 短文本字符串
BLOB 0-65 535字节 二进制形式的长文本数据
TEXT 0-65 535字节 长文本数据
MEDIUMBLOB 0-16 777 215字节 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215字节 中等长度文本数据
LONGBLOB 0-4 294 967 295字节 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295字节 极大文本数据

 如何选择VARCHAR和CHAR类型

VARCHAR和CHAR类型长度是以字符为定位的而不是字节,如UTF-8编码,每个字符占3个字节,那么CHAR(10)就需要占30个字节

VARCHAR类型的存储特点:

VARCHAR用于存储变长字符串,只占用必要的存储空间。

当列的最大长度小于255时,只占用一个额外字节用于记录字符串长度。

当列的最大长度大于255,则需要占用两个额外字节用于记录字符串长度。

VARCHAR长度选择问题:

使用最小的符合需求的长度。

系统上线后尽量不要修改VARCHAR的长度,因为在mysql 5.7之前,只要一修改就会发生锁表。

VARCHAR(5)和VARCHAR(200)存储'AAAAA'这一个字符串时都是使用一个额外的字节来记录字符串的长度,那么他们的性能有什么不同呢?

VARCHAR(5)优于VARCHAR(200)

因为MySQL为了能够更有效的优化查询,对于VARCHAR字段使用的是其最大的宽度来分配内存,所以如果我们把宽度定的太长就会消耗更多的内存。

VARCHAR类型的适用场景:

字符串列的最大长度比平均长度大很多

字符串列很少被更新

使用了多字节字符集存储字符串(如utf8中的中文和英文)


CHAR类型的存储特点:

CHAR类型是定长的

字符串存储在CHAR类型的列中会删除末尾的空格(VARCHAR则不会)

CHAR类型的最大宽度是255个字符,所以如果当我们长度超过255时,则需要使用VARCHAR类型进行存储

CHAR类型的适用场景:

存储长度近似的值(md5值,如密码)

存储短字符串

存储经常被更新的字符串列

1.3日期和时间类型 

类型 大小
(字节)
范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值
TIMESTAMP 4

1970-01-01 00:00:00/2038

结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07

YYYYMMDD HHMMSS 混合日期和时间值,时间戳

如何选择日期类型
   DATATIME类型

以yyyy-MM-dd HH:mm:ss[.fraction]格式存储日期时间

DATATIME = yyyy-MM-dd HH:mm:ss
DATATIME(6) = yyyy-MM-dd HH:mm:ss.fraction
与时区无关,占8个字节的存储空间

时间范围:1000-1-1 00:00:00至9999-12-31 23:59:59

TIMESTAMP类型

存储了由格林尼治时间1970-1-1 00:00:00到当前时间的秒数,以yyyy-MM-dd HH:mm:ss[.fraction]的格式显示,占用4个字节

时间范围:1970-1-1 到 2038-01-19

显示依赖于所指定的时区

在行的数据修改时可以自动修改TIMESTAMP列的值(设置为NOT NULL即可),默认是第一个为TIMESTAMP类型的列才会自动更新

DATE类型(如生日)

占用3个字节

使用DATE类型可以利用日期函数进行日期之间的计算

范围:1000-01-01到9999-12-31

TIME类型

HH:MM:SS
注意事项:

不要使用字符串类型存储日期时间数据

日期时间类型通常比字符串占用空间小

日期类型在进行查找过滤时可以利用日期来进行对比

可以利用日期函数进行日期之间的计算

使用Int存储日期时间不如使用TIMESTAMP类型

因为TIMESTAMP类型底层其实也是使用INT来存储的,只不过显示的时候格式化了而已,但更方便查看

2. 用SQL语句创建表 

2.1语句解释 

CREATE TABLE table_name (column_name column_type);##创建表的通用语句

2.2 设定列类型 、大小、约束

CREATE TABLE 表名 (列名 类型(大小) DEFAULT'默认值',
    
                    列名 类型(大小) DEFAULT'默认值',  

                    列名 类型(大小) DEFAULT'默认值',

                    ... ...);

 注:绿色部份是可以省略的。

2.2.1.定义完整性约束

USE 数据库名 CREATE TABLE 表名 (列名 类型(大小) DEFAULT'默认值' CONSTRAINT 约束名 约束定义,
                               列名 类型(大小) DEFAULT'默认值' CONSTRAINT 约束名 约束定义,  
                               列名 类型(大小) DEFAULT'默认值' CONSTRAINT 约束名 约束定义,

                               ... ...);

注:(1) 绿色部份是可以省略的。

          (2) 一个列是可以有多个约束的。

 约束定义:

(1)NULL | NOT NULL  用于定义列的空值约束。(定义列)  

            语法:CONSTRAINT 约束名 NULL | NOT NULL


            注意:

                    a. NOT NULL 约束强制列不接受 NULL 值。

                    b. NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新纪录或者更新记录。

            例:

                    下面的 SQL 语句强制 "Id_P" 列和 "LastName" 列不接受 NULL 值:

                     CREATE TABLE Persons
                     (
                     Id_P int NOT NULL,
                     LastName varchar(255) NOT NULL,
                     FirstName varchar(255),
                     Address varchar(255),
                     City varchar(255)
                     )

(2)UNIQUE  约束唯一标识数据库表中的每条记录。(即可以定义列也可能定义表)

            语法:CONSTRAINT 约束名 UNIQUE (列名, 列名, ... ...);

            说明:用于指定基本表在某一个列或多个列的组合上取值必须唯一。定义了UNIQUE约束的那些列称为唯一键。如果为基本表的革一列或多个列的组合指定了UNIQUE约束,则系统将为这些列建立唯一索引,从而保证在表中的任意两行记录在指定的列或列组合上不能取同样的值。

            注意:

                    a. UNIQUE 约束唯一标识数据库表中的每条记录。

                    b. UNIQUE 和 PRIMARY KEY 约束均为列或列集合提供了唯一性的保证。

                    c. PRIMARY KEY 拥有自动定义的 UNIQUE 约束。

                    d.请注意,每个表可以有多个 UNIQUE 约束,但是每个表只能有一个 PRIMARY KEY 约束。

           例:

                 下面的 SQL 在 "Persons" 表创建时在 "Id_P" 列创建 UNIQUE 约束:

               MySQL:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255),
                 UNIQUE (Id_P)
                 )

              SQL Server / Oracle / MS Access:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL UNIQUE,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255)
                  )

                 如果需要命名 UNIQUE 约束,以及为多个列定义 UNIQUE 约束,请使用下面的 SQL 语法:

              MySQL / SQL Server / Oracle / MS Access:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255),
                 CONSTRAINT uc_PersonID UNIQUE (Id_P,LastName)
                 )

(3)PRIMARY KEY 约束唯一标识数据库表中的每条记录。(即可以定义列也可能定义表)

            语法:CONSTRAINT 约束名 PRIMARY KEY (列名, 列名, ... ...);

            说明:用于定义基本表的主键。与UNIQUE约束类似,PRIMARY KEY 约束也是通过建立唯一索引来保证基本表在主键列(某一个列或多个列的组合)上取值的唯一性。然而它们之间也存在着很大差别:在一个基本表中只能定义一个 PRIMARY KEY 约束,却能定义多个UNIQUE约束。如果为基本表的某一个列或多个列的组合指定了 PRIMARY KEY 约束,那么其中在任何一个列都不能出现空值;而 UNIQUE 约束允许出现空值。

            注意:

                    a. 主键必须包含唯一的值。

                    b. 主键列不能包含 NULL 值。

                    c. 每个表应该都一个主键,并且每个表只能有一个主键。

            例:

                 下面的 SQL 在 "Persons" 表创建时在 "Id_P" 列创建 PRIMARY KEY 约束:

              MySQL:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255),
                 PRIMARY KEY (Id_P)
                 )

  如果需要命名 PRIMARY KEY 约束,以及为多个列定义 PRIMARY KEY 约束,请使用下面的 SQL 语法:

              MySQL / SQL Server / Oracle / MS Access:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255),
                 CONSTRAINT uc_PersonID PRIMARY KEY (Id_P,LastName)
                 )

(4)FOREIGN KEY 外键 (即可以定义列也可能定义表)

            语法:CONSTRAINT 约束名 FOREIGN KEY (列名, 列名, ... ...) REFERENCES (列名, 列名, ... ...) ;

            说明:指定某一个列或多个列的组合作为外部键,并在外部键和它所引用的主键或唯一键之间建立联系。在这种联系中,包含外部键的基本表称为从表,包含外部键引用的主键或唯一键的表称为主表。一旦为一列或列的组合定义了 FOREIGN KEY 约束,系统将保证从表在外部键上的取值要么是主表中某一个主键值或唯一键值,要么取空值。

            注意:

                    a.在REFERENCES 中引用的列必须和 FOREIGN KEY 的外部键列一一对应,即列数目相等并且相应列的数据类型相同。

            例:

                 下面的 SQL 在 "Orders" 表创建时为 "Id_P" 列创建 FOREIGN KEY:

                 MySQL:
                 CREATE TABLE Orders
                 (
                 O_Id int NOT NULL,
                 OrderNo int NOT NULL,
                 Id_P int,
                 PRIMARY KEY (O_Id),
                 FOREIGN KEY (Id_P) REFERENCES Persons(Id_P)
                 )

  如果需要命名 FOREIGN KEY 约束,以及为多个列定义 FOREIGN KEY 约束,请使用下面的 SQL 语法:

                 MySQL / SQL Server / Oracle / MS Access:
                 CREATE TABLE Orders
                 (
                 O_Id int NOT NULL,
                 OrderNo int NOT NULL,
                 Id_P int,
                 PRIMARY KEY (O_Id),
                 CONSTRAINT fk_PerOrders FOREIGN KEY (Id_P) REFERENCES Persons(Id_P)
                 ) 

    (5)CHECK 约束用于限制列中的值的范围。 (即可以定义列也可能定义表)

            语法:CONSTRAINT 约束名 CHECK (约束条件);

            说明:用于指定基本表中的每一条记录必须满足的条件,可以对基本表在各个列上的值做进一步的约束,如成绩列的取值既不能大于100,也不能小于0。

            注意:

                    a. 如果对单个列定义 CHECK 约束,那么该列只允许特定的值。

                    b. 如果对一个表定义 CHECK 约束,那么此约束会在特定的列中对值进行限制。

            例:

          下面的 SQL 在 "Persons" 表创建时为 "Id_P" 列创建 CHECK 约束。CHECK 约束规定 "Id_P" 列必须只包含大于 0 的整数。

                 My SQL:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255),
                 CHECK (Id_P>0)
                 )

 如果需要命名 CHECK 约束,以及为多个列定义 CHECK 约束,请使用下面的 SQL 语法:

                 MySQL / SQL Server / Oracle / MS Access:
                 CREATE TABLE Persons
                 (
                 Id_P int NOT NULL,
                 LastName varchar(255) NOT NULL,
                 FirstName varchar(255),
                 Address varchar(255),
                 City varchar(255),
                 CONSTRAINT chk_Person CHECK (Id_P>0 AND City='Sandnes')
                 )

-- 约束的目的 确保表中数据的完整性
 -- 行完整性(实体完整性):主键约束与唯一约束
 -- 列完整性(域完整性)  :检查约束、默认约束与非空约束
 -- 参照完整性  :外键约束

 -- 追加约束
-- 主键约束(向哪个表 加什么约束 加在哪个列上面) 非空唯一
alter table table_student
add constraint PK_id primary key(id)
alter table table_class
add constraint PK_class_id primary key(class_id)
-- 唯一约束  可以为空 但唯一 只允许一个为空
alter table table_student
add constraint UK_stu_number unique(stu_number)
--检查约束
alter table table_student
add constraint CK_stu_age check(stu_age>0 and stu_age<150)
--默认约束
alter table table_class
add constraint DF_create_time default(getdate()) for create_time
--外键约束
alter table table_student 
add constraint FK_class_id foreign key (class_id) references table_class(class_id)


--建表时直接加约束
 --create table table_student
--(
-- id int identity(1,1) primary key,
-- stu_number char(12) unique not null,
-- stu_name varchar(20) not null,
-- stu_age int check(stu_age>0 and stu_age<150),
-- birthday datetime default(getdate()),
-- class_id int references table_class(class_id)
-- )


--删除约束
alter table table_student
drop constraint UK_stu_number

3. 用SQL语句向表中添加数据 

使用 INSERT INTO SQL语句来插入数据。

3.1  以不指定列名的方式

insert  into 表名  values(值列表)[,(值列表)];       可以一次性插入多条数据。

 3.2 以指定列名的方式

insert into 表名  (字段列表) values (值列表)[,(值列表)];

 4. 用SQL语句删除表

删除MySQL数据表的通用语法:

DROP TABLE table_name ;

注:进行删除表操作时要非常小心,因为执行删除命令后所有数据都会消失。

 4.1 三种方式

 1、drop table 表名称                         eg: drop table  dbo.Sys_Test
  2、truncate table 表名称                     eg: truncate  table dbo.Sys_Test                  
  3、delete from 表名称 where 列名称 = 值      eg: delete from dbo.Sys_Test where test='test'

 4.2 drop,truncate,delete区别

 1、drop (删除表):删除内容和定义,释放空间。简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表。

       drop语句将删除表的结构被依赖的约束(constrain),触发器(trigger)索引(index);依赖于该表的存储过程/函数将被保留,但其状态会变为:invalid。

 2、truncate (清空表中的数据):删除内容、释放空间但不删除定义(保留表的数据结构)。与drop不同的是,只是清空表数据而已。

       注意:truncate 不能删除行数据,要删就要把表清空。

  3、delete (删除表中的数据):delete 语句用于删除表中的行。delete语句执行删除的过程是每次从表中删除一行,并且同时将该行的删除操作作为事务记录在日志中保存

       以便进行进行回滚操作。

       truncate与不带where的delete :只删除数据,而不删除表的结构(定义)

    4、truncate table 删除表中的所有行,但表结构及其列、约束、索引等保持不变。新行标识所用的计数值重置为该列的种子。如果想保留标识计数值,请改用delete。

       如果要删除表定义及其数据,请使用 drop table 语句。  
    5、对于由foreign key约束引用的表,不能使用truncate table ,而应使用不带where子句的delete语句。由于truncate table 记录在日志中,所以它不能激活触发器。

    6、执行速度,一般来说: drop> truncate > delete。

    7、delete语句是数据库操作语言(dml),这个操作会放到 rollback segement 中,事务提交之后才生效;如果有相应的 trigger,执行的时候将被触发。

         truncate、drop 是数据库定义语言(ddl),操作立即生效,原数据不放到 rollback segment 中,不能回滚,操作不触发 trigger。 

在实际应用中,三者的区别是明确的。

当你不再需要该表时, 用 drop;

当你仍要保留该表,但要删除所有记录时, 用 truncate;

当你要删除部分记录时(always with a WHERE clause), 用 delete.

5.用SQL语句修改表 

 5.1 修改表名

rename 旧表名 to 新表名;

5.2 新建列 

 alter table 表名 add 列名 varchar(30)

5.3 删除列 

alter table 表名 drop column 列名

注:若要删除某个列的值,利用update设置为null 

如:update  表名 set 列名=null  where 条件

5.4 修改列名 

 alter table 表名 rename column 【列名】 to 【新列名】;

5.5修改表中数据

update 表名 SET 列名 = 新值 WHERE 列名 = 某值

即 update 员工表 set 部门id=01 where 员工id=0004

5.6 新建行

 insert into 列名(字段1,字段2...)values (字段1,字段2....) ;

5.7 删除行

 delete from 表名 where 条件

参考: 

https://blog.csdn.net/Qingqinglanghua/article/details/5051563

https://blog.csdn.net/zoweiccc/article/details/75948719

项目练习

 项目三:超过5名学生的课(难度:简单)

创建如下所示的courses 表 ,有: student (学生) 和 class (课程)。 

建表和插入数据:

create table courses (
student char(10) not null,
class varchar(50) not null
);


/*插入数据*/

insert into courses values('A','Math');
insert into courses values('B','English ');
insert into courses values('C','Math');
insert into courses values('D','Biology');
insert into courses values('E','Math');
insert into courses values('F','Computer');
insert into courses values('G','Math');
insert into courses values('H','Math');
insert into courses values('I','Math');
insert into courses values('A','Math');

创建表如下:

 

 编写一个 SQL 查询,列出所有超过或等于5名学生的课。Note: 学生在每个课中不应被重复计算

SELECT class
FROM courses
GROUP BY class
HAVING count(DISTINCT student)>=5;

结果为:

 

项目四:交换工资(难度:简单)

创建一个 salary表,如下所示,有m=男性 和 f=女性的值 。 

 

交换所有的 f 和 m 值(例如,将所有 f 值更改为 m,反之亦然)。要求使用一个更新查询,并且没有中间临时表。 

猜你喜欢

转载自blog.csdn.net/nowfuture/article/details/88049696
今日推荐