MySQL-2 - 機能と制約 (ケーススタディと組み合わせたもの)

関数

関数は、別のプログラムから直接呼び出すことができるプログラムまたはコードの一部です。つまり、このプログラムまたはコードは MySQL で提供されており、必要なのは、適切なビジネス シナリオで対応する関数を呼び出して、対応するビジネス要件を完了することだけです。
MySQL の関数は主に、文字列関数、数値関数、日付関数、処理関数の 4 つのカテゴリに分類されます。
その使い方は、select 函数

文字列関数

共通機能

関数 関数
CONCAT(s1, s2, …, sn) 文字列の結合、s1、s2、...、sn を文字列に結合
CONCAT_WS(s,s1, s2, …, sn) 文字列を結合するためのコネクタとして s を使用し、s1、s2、...、sn を文字列に結合します。中央のコネクタは s です。
下限(文字列) すべての文字列を小文字に変換します
アッパー(str) 文字列をすべて大文字に変換する
LPAD(str, n, パッド) 左パディング。n 文字列の長さに達するまで、str の左側を文字列パッドで埋めます。
RPAD(str, n, パッド) 右パディング。n 個の文字列の長さに達するまで、str の右側を文字列パッドで埋めます。
トリム(文字列) LTRIMやRTRIMと同様に、文字列の先頭と末尾のスペースを削除します(文字列の途中は処理されません)。
SUBSTRING(str, start, len) 文字列 str の開始位置から len の長さの文字列を、1 からインデックス付けして返します。

使用法

  • ステッチ
    SELECT CONCAT('Hello', 'World');
  • カンマで連結する
    SELECT CONCAT_WS(',','Hello', 'World');
  • 小文字
    SELECT LOWER('Hello');
  • 資本
    SELECT UPPER('Hello');
  • 左パディング
    SELECT LPAD('01', 5, '-');
  • 右パディング
    SELECT RPAD('01', 5, '-');
  • スペースを削除する
    SELECT TRIM(' Hello World ');
  • スライス (開始インデックスは 1)
    SELECT SUBSTRING('Hello World', 1, 5);ここでのインデックスは 0 ではなく 1 から始まることに注意してください。

知らせ

  • 文字列関数の文字列が純粋な数値 (数値データ) の場合、MySQL は内部で自動的に文字列に変換して操作します。
    ここに画像の説明を挿入

  • パディングが長さ 5 にパディングされる場合、パディング 5 ではなく長さ 5。

  • 塗りつぶし時にパッドが長すぎる場合は、塗りつぶす部分として左からn-len(str)文字が選択されます。
    ここに画像の説明を挿入

  • 埋めるときに、n>len(str) の場合、str の左から n 文字が最終結果として選択されます。
    ここに画像の説明を挿入

  • rpad とラップには、上記の特殊なケースに対する同じ処理ルールがあります。

  • これらはすべて文字列関数であるため、生成されるデータは文字列データである必要があります。たとえば、このコードをidupdate emp set id = lpad(id,5,0)列に使用しても、生成される文字列は文字列ですが、id 列には数値データが格納されるため、効果はありません。したがって、生成された結果は id に割り当てられませんが、select lpad(id,5,0) from emp;生成された文字列は出力できるため有効になります。

ケース

ビジネス要件の変化により、企業従業員の役職番号は 5 桁に統一され、8 桁未満の場合は先頭に 0 が埋め込まれます。例: 従業員 No. 1 のジョブ番号は 00000001 となります。
update emp set workno = lpad(workno,8,0);

数値関数

共通機能

関数 関数
CEIL(x) 切り上げ
フロア(x) 切り捨て
MOD(x, y) x/y の係数を返します。
ランド() 0 から 1 までの乱数を返します
ROUND(x, y) パラメーター x の四捨五入された値を見つけ、小数点以下 y を保持します
pow(x, y) xy {x^y}バツy
exp(x) e x {e^x} eバツ
sqrt(x) x {\sqrt x}を見つけますバツ

使用法

  • 天井:切り上げ
    select ceil(1.1);
  • 床:切り捨て
    select floor(1.9);
  • mod:モジュロ
    select mod(7,4);
  • rand: 乱数を取得する
    select rand();
  • 丸い:丸い
    select round(2.344,2);

ケース

データベースの機能により、6 桁のランダムな認証コードが生成されます。
アイデア: rand() 関数で乱数を取得できますが、取得した乱数は 0 ~ 1 なので、
1000000 を乗算し、小数部分を切り捨てることができます。長さが 6 桁未満の場合は、 0を追加します。
select lpad(floor(rand()*1000000),6,0);また
select lpad(round(rand()*1000000,0),6,0);

日付関数

共通機能

関数 関数
CURDATE() 現在の日付を返す
時間() 現在時刻を返す
今() 現在の日付と時刻を返します
DATE(日付) 指定した日付の日付「年-月-日」を取得します
時間(日付) 指定した日付の時刻「時:分:秒」を取得します
年(日付) 指定した日付の年を取得します
月(日付) 指定した日付の月を取得します
DAY(日付) 指定した日付の日数を取得します
時間(日付) 指定した日付の時間を取得します
分(日付) 指定した日付の分を取得します
SECOND(日付) 指定した日付の秒を取得します
DATE_ADD(日付、INTERVAL式型) 日付/時刻値と間隔 expr の後の時刻値を返します。
ADDTIME(日付, 時刻) 日付/時刻に時刻を加算した結果を「日時:分:秒」の形式で返します。
DATE_SUB(日付、INTERVAL式型) 日付/時刻の値から時間間隔の式を引いた値を返します。
DATEDIFF(日付1, 日付2) 開始時刻 date1 と終了時刻 date2 の間の日数を整数で返します。
TIMEDIFF(時間1, 時間2) 開始時刻 time1 と終了時刻 time2 の時間差を返します。時:分:秒を返します。
TIME_TO_SEC(時間) 時間を秒に変換します。入力時間の形式は時:分:秒で、整数の秒を返します。

使用方法(一部のみ表示)

  • curdate: 現在の日付
    select curdate();
  • curtime: 現在時刻
    select curtime();
  • now: 現在の日付と時刻
    select now();
  • YEAR 、MONTH 、DAY 、HOUR 、MINUTE 、SECOND: 年、月、日、時、分、秒。
    select YEAR(now()),MONTH(now()),DAY(now()),HOUR(now()),MINUTE(now()),SECOND(now());

  • select date_add(now(), INTERVAL 2 HOUR);
    date_add: 指定した時間間隔を追加するには、YEAR、MONTH、DAY、HOUR、MINUTE、SECOND、YEAR_MONTH、MONTH_DAY など、さまざまなタイプがあります。YEAR_MONTH
    を使用する方法はselect date_add(now(), INTERVAL 4.2 YEAR_MONTH );(4 年 2 か月を追加することを意味します)
  • addtime:增加指定的时间间隔
    select addtime(now(),'5 240:0:0'); 增加5天后增加240个小时(一共15天)
  • datediff:获取两个日期相差的天数
    select datediff('2021-12-01','2021-10-01');
  • timediff:获取两个日期相差的时间
    select timediff('2022-10-05 18:45:09','2022-09-04 18:45:09');

案例

查询所有员工的入职天数,并根据入职日期倒序排序。
思路: 入职天数,就是通过当前日期 - 入职日期,所以需要使用datediff函数来完成。对于在同一天入职的员工,我们可以使用相同的方法首先用timediff函数获得时间差,然后再通过time_to_sec来换成秒数进行比较入职的时间就可以了。

select name, datediff(now(),entrydate) as 'entrydays', entrydate from emp order by entrydays, time_to_sec(timediff(now(),TIME(entrydate)));
当然MySQL也可以自动排序
select name, datediff(now(),entrydate), entrydate from emp order by entrydate desc;

流程函数

常用函数

函数 功能
IF(value, t, f) 如果value为true,则返回t,否则返回f
IFNULL(value1, value2) 如果value1不为空,返回value1,否则返回value2
CASE WHEN [ val1 ] THEN [ res1 ] … ELSE [ default ] END 如果val1为true,返回res1,… 否则返回default默认值
CASE [ expr ] WHEN [ val1 ] THEN [ res1 ] … ELSE [ default ] END 如果expr的值等于val1,返回res1,… 否则返回default默认值

用法

  • if
    select if(true ,'ok','error');
  • ifnull
    select if(true ,'ok','error');
    select ifnull(null,'default');
    select ifnull('','default');
  • case when then else end
    查询emp表的员工姓名和工作地址 (北京/上海 ----> 一线城市 , 其他 ----> 二线城市)
    select name, workaddress, case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end from emp;

案例

统计班级各个学员的成绩,展示的规则如下:

>=85 : 展示优秀
>=60:展示及格
否则 :不及格

导入成绩:

create table score( id int comment 'ID',
name varchar(20)
    comment '姓名',
    math int comment '数学',
    english int comment '英语',
    chinese int comment '语文' 
    )comment '学员成绩表';
insert into score(id, name, math, english, chinese)
VALUES (1, 'Tom', 67, 88, 95 ),
       (2, 'Rose' , 23, 66, 90),
       (3, 'Jack', 56, 98, 76);

本案例的语句如下:

select name,
       case when math>=85 then '优秀' when math>60 then '及格' else '不及格' end as 'math',
       case when english>=85 then '优秀' when english>60 then '及格' else '不及格' end as 'englise',
       case when chinese>=85 then '优秀' when chinese>60 then '及格' else '不及格' end as 'chinese'
from score;

约束

概述

概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据,可以再创建表/修改表的时候添加约束。
目的:保证数据库中数据的正确、有效性和完整性。
分类:

约束 描述 关键字
非空约束 限制该字段的数据不能为null NOT NULL
唯一约束 保证该字段的所有数据都是唯一、不重复的 UNIQUE
主键约束 主键是一行数据的唯一标识,要求非空且唯一 PRIMARY KEY
默认约束 保存数据时,如果未指定该字段的值,则采用默认值 DEFAULT
检查约束(8.0.1版本后) 保证字段值满足某一个条件 CHECK
外键约束 用来让两张图的数据之间建立连接,保证数据的一致性和完整性 FOREIGN KEY

语法:在字段类型之后加上约束的关键字即可 字段 类型 约束关键字1 约束关键字2 约束关键字3...

前五个约束演示

ここに画像の説明を挿入
创建

create table user_ys(
    id int primary key auto_increment comment '主键',
    name varchar(10) not null unique comment '姓名',
    age int check ( age>0 && age<=120 ) comment '年龄',
    status char(1) default '1' comment '状态',
    gender char(1) comment '性别'
)comment '约束用户表';

修改

alter table user_ys modify status char(1) default '0';
alter table user_ys modify status char(1) default '1';

验证

insert into user_ys(name, age, status, gender)  #主键会自动增长,不需要手动添加
values('Tom1',19,1,'男'),
      ('Tom2',25,0,'男'),
      ('Tom3',19,1,'男');  
          
#测试 NOT NULL
insert into user_ys(name, age, status, gender) values (null,19,'1','男');
#测试 UNIQUE
insert into user_ys(name, age, status, gender) values ('Tom3',20,'0','男');

insert into user_ys(name, age, status, gender) values ('Tom4',80,'1','男');  
#id为5,因为在添加'Tom3'的时候已经向数据库发送了请求,所以主键已经加了1。

#测试 CHECK
insert into user_ys(name, age, status, gender) values ('Tom5',-1,'0','男');
insert into user_ys(name, age, status, gender) values ('Tom5',121,'0','男');

#测试 DEFAULT
insert into user_ys(name, age, gender) values ('Tom5',120,'男');
             

注意:唯一键冲突和事务回滚都会导致自增主键id不连续的情况

外键约束演示

外键解释

外键:用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性
如图所示:
ここに画像の説明を挿入左侧的emp表是员工表,里面存储员工的基本信息,包含员工的ID、姓名、年龄、职位、薪资、入职日期、上级主管ID、部门ID,
在员工的信息中存储的是部门的ID dept_id
而这个部门的ID dept_id 关联着右侧的部门表dept的主键 id
那emp表的dept_id就是外键,关联的是dept表的主键
emp表被称为子表或者从表;
dept表被称为父表或者主表。

注意:目前上述两张表,只是在逻辑上存在这样一层关系;在数据库层面,并未建立外键关联,所以是无法保证数据的一致性和完整性的,看下面的例子。

1. 准备数据:

drop table if exists emp;

create table dept ( id int auto_increment comment 'ID' primary key,
                      name varchar (50) not null comment '部门名称'
) comment '部门表';

INSERT INTO dept ( id,name) VALUES (1,'研发部'), (2,'市场部'),(3,'财务部'),(4,'销售部'),(5,'总经办');

create table emp(
    id int auto_increment comment 'ID' primary key,
    name varchar(50) not null comment '姓名',
    age int comment '年龄', job varchar(20) comment '职位',
    salary int comment '薪资', entrydate date comment '入职时间',
    managerid int comment '直属领导ID',
    dept_id int comment '部门ID'
)comment '员工表';

INSERT INTO emp (id, name, age, job,salary, entrydate, managerid, dept_id)
VALUES (1, '金庸', 66, '总裁',20000, '2000-01-01', null,5),
       (2, '张无忌', 20, '项目经理',12500, '2005-12-05', 1,1),
       (3, '杨逍', 33, '开发', 8400,'2000-11-03', 2,1),
       (4, '韦一笑', 48, '开 发',11000, '2002-02-05', 2,1),
       (5, '常遇春', 43, '开发',10500, '2004-09-07', 3,1),
       (6, '小昭', 19, '程 序员鼓励师',6600, '2004-10-12', 2,1);

2. 测试,删除id为1的部门信息。

delete from dept where id=1;
此时emp表不再有主键id=1的部门,但是dept中还有外键dept_id=1,所以如果不降两张表关联,就会导致数据的不完整性。ここに画像の説明を挿入ここに画像の説明を挿入

外键约束语法

创建

CREATE TABLE 表名(
	字段名 字段类型,
	...
	[CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) REFERENCES 主表(主表列名)
);
# references 指定的主表只能是已创建的主表。

修改

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);

删除

ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;

举例

创建:
create table emp_test(
                    id int auto_increment comment 'ID' primary key,
                    name varchar(50) not null comment '姓名',
                    age int comment '年龄', job varchar(20) comment '职位',
                    salary int comment '薪资', entrydate date comment '入职时间',
                    managerid int comment '直属领导ID',
                    dept_id int comment '部门ID',
                    constraint dk_emp_dept_id foreign key (dept_id) references dept(id)
)comment '员工表';
#上面的只是展示创建语句,删除即可
修改
insert into dept
values(1,'研发部');  #加回来

alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id);

修改完可以在emp表中看到下面的变化:
ここに画像の説明を挿入

此时如果执行上面的删除命令delete from dept where id=1;,会报错
ここに画像の説明を挿入
即告诉我们不能删除一个父表的记录,因为子表中外键与其关联。

删除刚刚创建的外键

alter table emp drop foreign key fk_emp_dept_id;

外键增加数据行为

如果在子表中添加的数据外键不在父表中,则会报错,但是外键可以为NULL,表示待分配。

外键删除更新行为

分类

添加了外键之后,再删除父表数据时产生的约束行为,我们就称为删除/更新行为。具体的删除/更新行为有以下几种:

行为 说明
NO ACTION 親テーブル内の対応するレコードを削除/更新する場合、最初にレコードに対応する外部キーがあるかどうかを確認し、存在する場合は削除/更新は許可されません (RESTRICT と一致します)。
制限 親テーブル内の対応するレコードを削除/更新するときは、最初にレコードに対応する外部キーがあるかどうかを確認し、存在する場合は削除/更新は許可されません (NO ACTION と一致します)。
CASCADE(シリアル接続) 親テーブルの該当レコードを削除・更新する場合は、まずそのレコードに対応する外部キーがあるかどうかを確認し、あれば子テーブルの外部キーレコードを削除・更新します。
NULL を設定 親テーブルの対応するレコードを削除/更新する場合、まずレコードに対応する外部キーがあるかどうかを確認し、存在する場合は子テーブルの外部キー値を null に設定します (外部キーは null を許可する必要があります)。
デフォルトを設定 親テーブルが変更されると、子テーブルは外部キーをデフォルト値に設定します (Innodb はサポートしません)

文法

ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名 (主表字段名) ON UPDATE 行为 ON DELETE 行为;

デモ

NO ACTION がデフォルトの動作であるため、前の構文のデモですでにテスト済みであるため、再度のデモンストレーションは行いませんが、ここでは他の 2 つの動作、CASCADE と SET NULL をデモンストレーションします。

  1. 削除と更新 - カスケード
    alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update cascade on delete cascade;
  • 埋め込む:update dept set id = 6 where id = 1;
    ここに画像の説明を挿入
    ここに画像の説明を挿入
  • 埋め込む:delete from dept where id = 5;
    ここに画像の説明を挿入
    ここに画像の説明を挿入
  1. SET NULL は
    、まず 2 つのテーブルを手動で削除して再作成し、次に外部キーを作成します。
    alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id) on update set null on delete set null;
  • 埋め込む:delete from dept where id = 1;
    ここに画像の説明を挿入ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_49030008/article/details/126680878