首页
关于
Search
1
给你10个市场数据调研报告的免费下载网站!以后竞品数据就从这里找!
182 阅读
2
php接口优化 使用curl_multi_init批量请求
144 阅读
3
《从菜鸟到大师之路 ElasticSearch 篇》
107 阅读
4
2024年备考系统架构设计师
104 阅读
5
PHP 文件I/O
92 阅读
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
登录
Search
标签搜索
php函数
php语法
性能优化
安全
错误和异常处理
问题
vue
Composer
Session
缓存
框架
Swoole
api
并发
异步
正则表达式
php-fpm
mysql 索引
开发规范
协程
dafenqi
累计撰写
786
篇文章
累计收到
28
条评论
首页
栏目
php
thinkphp
laravel
工具
开源
mysql
数据结构
总结
思维逻辑
令人感动的创富故事
读书笔记
前端
vue
js
css
书籍
开源之旅
架构
消息队列
docker
教程
代码片段
副业
redis
服务器
nginx
linux
科普
java
c
ElasticSearch
测试
php进阶
php基础
页面
关于
搜索到
560
篇与
的结果
2024-02-05
掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了
掌握 SQL 这些核心知识点,出去吹牛逼再也不担心了第一章 SQL的介绍1.1什么是sqlSQL:Structure Query Language。(结构化查询语言),通过sql操作数据库(操作数据库,操作表,操作数据)SQL被美国国家标准局(ANSI)确定为关系型数据库语言的美国标准,后来被国际化标准组织(ISO)采纳为关系数据库语言的国际标准各数据库厂商(MySql,oracle,sql server)都支持ISO的SQL标准。各数据库厂商在标准的基础上做了自己的扩展。 各个数据库自己特定的语法1.2 sql的分类Data Definition Language (DDL数据定义语言) 如:操作数据库,操作表Data Manipulation Language(DML数据操纵语言),如:对表中的记录操作增删改Data Query Language(DQL 数据查询语言),如:对表中数据的查询操作Data Control Language(DCL 数据控制语言),如:对用户权限的设置1.3 MySQL的语法规范和要求(1)mysql的sql语法不区分大小写MySQL的关键字和函数名等不区分大小写,但是对于数据值是否区分大小写,和字符集与校对规则有关。ci(大小写不敏感),cs(大小写敏感),_bin(二元,即比较是基于字符编码的值而与language无关,区分大小写)(2)命名时:尽量使用26个英文字母大小写,数字0-9,下划线,不要使用其他符号user_id(3)建议不要使用mysql的关键字等来作为表名、字段名等,如果不小心使用,请在SQL语句中使用`(飘号)引起来(4)数据库和表名、字段名等对象名中间不要包含空格(5)同一个mysql软件中,数据库不能同名,同一个库中,表不能重名,同一个表中,字段不能重名(6)标点符号:必须成对必须英文状态下半角输入方式字符串和日期类型可以使用单引号’’列的别名可以使用双引号"",给表名取别名不要使用双引号。取别名时as可以省略如果列的别名没有包含空格,可以省略双引号,如果有空格双引号不能省略。(7)SQL脚本中如何加注释单行注释:#注释内容单行注释:--空格注释内容 其中--后面的空格必须有多行注释:/* 注释内容 */#以下两句是一样的,不区分大小写 show databases; SHOW DATABASES; #创建表格 #create table student info(...); #表名错误,因为表名有空格 create table student_info(...); #其中name使用``飘号,因为name和系统关键字或系统函数名等预定义标识符重名了。 CREATE TABLE t_stu( id INT, `name` VARCHAR(20) ); select id as "编号", `name` as "姓名" from t_stu; #起别名时,as都可以省略 select id as 编号, `name` as 姓名 from t_stu; #如果字段别名中没有空格,那么可以省略"" select id as 编 号, `name` as 姓 名 from t_stu; #错误,如果字段别名中有空格,那么不能省略""第二章-DDL操作数据库2.1创建数据库(掌握)语法create database 数据库名 [character set 字符集][collate 校对规则] 注: []意思是可选的意思字符集(charset):是一套符号和编码。练习创建一个day01的数据库(默认字符集)create database day01;创建一个day01_2的数据库,指定字符集为gbk(了解)create database day01_2 character set gbk;2.2查看所有的数据库2.2.1查看所有的数据库语法show databases; 2.2.2查看数据库的定义结构【了解】语法show create database 数据库名;查看day01这个数据库的定义show create database day01; 2.3删除数据库语法drop database 数据库名;删除day01_2数据库drop database day01_2;2.4修改数据库【了解】语法alter database 数据库名 character set 字符集修改day01这个数据库的字符集(gbk)alter database day01 character set gbk;注意:是utf8,不是utf-8不是修改数据库名2.5其他操作切换数据库, 选定哪一个数据库use 数据库名; //注意: 在创建表之前一定要指定数据库. use 数据库名练习: 使用day01use day01;查看正在使用的数据库select database();第三章-DDL操作表3.1 创建表3.1.1 语法create table 表名( 列名 类型 [约束], 列名 类型 [约束] ... );3.1.2 类型3.1.2.1 数值类型整型系列:xxxIntint(M),必须和unsigned zerofill一起使用才有意义浮点型系列:float,double(或real)double(M,D):表示最长为M位,其中小数点后D位例如:double(5,2)表示的数据范围[-999.99,999.99],如果超过这个范围会报错。定点型系列:decimal(底层实际上是使用字符串进行存储)decimal(M,D):表示最长为M位,其中小数点后D位位类型:bit字节范围是:1-8,值范围是:bit(1)~bit(64),默认bit(1)用来存储二进制数。对于位字段,直接使用select命令将不会看到结果。可以使用bit()或hex()函数进行读取。插入bit类型字段时,使用bit()函数转为二进制值再插入,因为二进制码是“01”。3.1.2.2 日期时间类型日期时间类型:year, date, datetime, timestamp注意一下每一种日期时间的表示范围timestamp和datetime的区别:timestamp范围比较小timestamp和时区有关show variables like ‘time_zone’;set time_zone = ‘+8:00’;timestamp受MySQL版本和服务器的SQLMode影响很大表中的第一个非空的timestamp字段如果插入和更新为NULL则会自动设置为系统时间3.1.2.3 字符串类型MySQL中提供了多种对字符数据的存储类型,不同的版本可能有所差异。常见的有:char,varchar,xxtext,binary,varbinary,xxblob,enum,set等等字符串类型char,varchar(M)char如果没有指定宽度,默认为1个字符varchar(M),必须指定宽度binary和varbinary类似于char和varchar,不同的是它们包含二进制字符串,不支持模糊查询之类的。一般在保存少量字符串的时候,我们会选择char和varchar;而在保存较大文本时,通常会选择使用text或blob系列。blob和text值会引起一些性能问题,特别是在执行了大量的删除操作时,会在数据表中留下很大的“空洞”,为了提高性能,建议定期时候用optimize table功能对这类表进行碎片整理。可以使用合成的(Synthetic)索引来提高大文本字段的查询性能,如果需要对大文本字段进行模糊查询,MySql提供了前缀索引。但是仍然要在不必要的时候避免检索大型的blob或text值。enum枚举类型,它的值范围需要在创建表时通过枚举方式显式指定,对于1~255个成员的枚举需要1个字节存储;对于255`65535个成员需要2个字节存储。例如:gender enum(‘男’,‘女’)。如果插入枚举值以外的值,会按第一个值处理。一次只能从枚举值中选择一个。set集合类型,可以包含0~64个成员。一次可以从集合中选择多个成员。如果选择了1-8个成员的集合,占1个字节,依次占2个,3个。。8个字节。例如:hoppy set(‘吃饭’,‘睡觉’,‘玩游戏’,‘旅游’),选择时’吃饭,睡觉’或’睡觉,玩游戏,旅游’3.1.2.4 示例+----------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------+----------------+ | eid | int(11) | NO | PRI | NULL | auto_increment | | ename | varchar(20) | NO | | NULL | | | tel | char(11) | NO | | NULL | | | gender | char(1) | YES | | 男 | | | salary | double | YES | | NULL | | | commission_pct | double(3,2) | YES | | NULL | | | birthday | date | YES | | NULL | | | hiredate | date | YES | | NULL | | | job_id | int(11) | YES | | NULL | | | email | varchar(32) | YES | | NULL | | | mid | int(11) | YES | | NULL | | | address | varchar(150) | YES | | NULL | | | native_place | varchar(10) | YES | | NULL | | | did | int(11) | YES | | NULL | | +----------------+--------------+------+-----+---------+----------------+ 3.1.3 约束即规则,规矩 限制;作用:保证用户插入的数据保存到数据库中是符合规范的约束 约束关键字 主键 primary key 非空且唯一,并且一张表只能有一个主键唯一 unique 唯一,当前列不能出现相同的数据非空 not null 非空,当前列不能为null默认 default 如果当前列没有数据,则指定默认数据约束种类:not null: 非空 ; eg: username varchar(40) not null username这个列不能有null值unique:唯一约束, 后面的数据不能和前面重复; eg: cardNo char(18) unique; cardNo 列里面不可以有重复数据primary key;主键约束(非空+唯一); 一般用在表的id列上面. 一张表基本上都有id列的, id列作为唯一标识的auto_increment: 自动增长,必须是设置了primary key之后,才可以使用auto_incrementid int primary key auto_increment; id不需要我们自己维护了, 插入数据的时候直接插入null, 自动的增长进行填充进去, 避免重复了.注意:先设置了primary key 再能设置auto_increment只有当设置了auto_increment 才可以插入null , 否则插入null会报错id列:给id设置为int类型, 添加主键约束, 自动增长或者给id设置为字符串类型,添加主键约束, 不能设置自动增长3.1.4练习创建一张学生表(含有id字段,姓名字段不能重复,性别字段不能为空默认值为男. id为主键自动增长)CREATE TABLE student( id INT PRIMARY KEY AUTO_INCREMENT, -- 主键自增长 NAME VARCHAR(30) UNIQUE, -- 唯一约束 gender CHAR(1) NOT NULL DEFAULT '男' );3.2 查看表【了解】3.2.1查看所有的表show tables;3.2.2查看表的定义结构语法desc 表名;练习: 查看student表的定义结构desc student;3.3 修改表【掌握,但是不要记忆】3.3.1语法增加一列alter table 【数据库名.]表名称 add 【column】 字段名 数据类型; alter table 【数据库名.]表名称 add 【column】 字段名 数据类型 first; alter table 【数据库名.]表名称 add 【column】 字段名 数据类型 after 另一个字段;修改列的类型约束:alter table 表名 modify 字段 类型 约束 ;修改列的名称,类型,约束: alter table 表名 change 旧列 新列 类型 约束;删除一列: alter table 表名 drop 列名;修改表名 : rename table 旧表名 to 新表名;3.3.2练习给学生表增加一个grade字段,类型为varchar(20),不能为空ALTER TABLE student ADD grade VARCHAR(20) NOT NULL;给学生表的gender字段改成int类型,不能为空,默认值为1alter table student modify gender varchar(20); 给学生表的grade字段修改成class字段ALTER TABLE student CHANGE grade class VARCHAR(20) NOT NULL;把class字段删除ALTER TABLE student DROP class;把学生表修改成老师表(了解)RENAME TABLE student TO teacher;3.4 删除表【掌握】语法drop table 表名;把teacher表删除drop table teacher;第四章-DML操作表记录-增删改【重点】准备工作: 创建一张商品表(商品id,商品名称,商品价格,商品数量.)create table product( pid int primary key auto_increment, pname varchar(40), price double, num int );4.1 插入记录4.1.1 语法方式一: 插入指定列, 如果没有把这个列进行列出来, 以null进行自动赋值了.eg: 只想插入pname, price , insert into t_product(pname, price) values(‘mac’,18000); insert into 表名(列,列..) values(值,值..);注意: 如果没有插入了列设置了非空约束, 会报错的方式二: 插入所有的列,如果哪列不想插入值,则需要赋值为nullinsert into 表名 values(值,值....); eg: insert into product values(null,'苹果电脑',18000.0,10); insert into product values(null,'华为5G手机',30000,20); insert into product values(null,'小米手机',1800,30); insert into product values(null,'iPhonex',8000,10); insert into product values(null,'iPhone7',6000,200); insert into product values(null,'iPhone6s',4000,1000); insert into product values(null,'iPhone6',3500,100); insert into product values(null,'iPhone5s',3000,100); insert into product values(null,'方便面',4.5,1000); insert into product values(null,'咖啡',11,200); insert into product values(null,'矿泉水',3,500);4.2 更新记录4.2.1语法update 表名 set 列 =值, 列 =值 [where 条件]4.2.2练习将所有商品的价格修改为5000元update product set price = 5000;UPDATE product set price = 18000 WHERE pname = '苹果电脑';将商品名是苹果电脑的价格修改为17000,数量修改为5UPDATE product set price = 17000,num = 5 WHERE pname = '苹果电脑';将商品名是方便面的商品的价格在原有基础上增加2元UPDATE product set price = price+2 WHERE pname = '方便面';4.3 删除记录4.3.1 delete根据条件,一条一条数据进行删除语法delete from 表名 [where 条件] 注意: 删除数据用delete,不用truncate类型删除表中名称为’苹果电脑’的记录delete from product where pname = '苹果电脑';删除价格小于5001的商品记录delete from product where price < 5001;删除表中的所有记录(要删除一般不建议使用delete语句,delete语句是一行一行执行,速度过慢)delete from product;4.3.2truncate把表直接DROP掉,然后再创建一个同样的新表。删除的数据不能找回。执行速度比DELETE快truncate table 表;4.3.3 工作中删除数据物理删除: 真正的删除了, 数据不在, 使用delete就属于物理删除逻辑删除: 没有真正的删除, 数据还在. 搞一个标记, 其实逻辑删除是更新 eg: state 1 启用 0禁用第五章-DQL操作表记录-查询【重点】5.1 基本查询语法select 要查询的字段名 from 表名 [where 条件] 5.2 简单查询5.2.1 查询所有行和所有列的记录语法select * form 表查询商品表里面的所有的列select * from product;5.2.2 查询某张表特定列的记录语法select 列名,列名,列名... from 表查询商品名字和价格select pname, price from product;5.2.3 去重查询 distinct语法SELECT DISTINCT 字段名 FROM 表名; //要数据一模一样才能去重去重查询商品的名字SELECT DISTINCT pname,price FROM product注意点: 去重针对某列, distinct前面不能先出现列名5.2.4 别名查询语法select 列名 as 别名 ,列名 from 表 //列别名 as可以不写 select 别名.* from 表 as 别名 //表别名(多表查询, 明天会具体讲)查询商品信息,使用别名SELECT pid ,pname AS '商品名',price AS '商品价格',num AS '商品库存' FROM product5.2.5 运算查询(+,-,*,/,%等)把商品名,和商品价格+10查询出来:我们既可以将某个字段加上一个固定值,又可以对多个字段进行运算查询select pname ,price+10 as 'price' from product; select name,chinese+math+english as total from student注意运算查询字段,字段之间是可以的字符串等类型可以做运算查询,但结果没有意义5.3 条件查询(很重要)5.3.1语法select ... from 表 where 条件 //取出表中的每条数据,满足条件的记录就返回,不满足条件的记录不返回5.3.2 运算符1、比较运算符大于:>小于:<大于等于:>=小于等于:<=等于:= 不能用于null判断不等于:!= 或 <>安全等于: <=> 可以用于null值判断2、逻辑运算符(建议用单词,可读性来说)逻辑与:&& 或 and逻辑或:|| 或 or逻辑非:! 或 not逻辑异或:^ 或 xor3、范围区间范围:between x and y not between x and y集合范围:in (x,x,x) not in (x,x,x)4、模糊查询和正则匹配(只针对字符串类型,日期类型)like 'xxx' 模糊查询是处理字符串的时候进行部分匹配如果想要表示0~n个字符,用%如果想要表示确定的1个字符,用_regexp '正则'5、特殊的null值处理#(1)判断时 xx is null xx is not null xx <=> null #(2)计算时 ifnull(xx,代替值) 当xx是null时,用代替值计算5.3.3 练习查询商品价格>3000的商品select * from product where price > 3000;查询pid=1的商品select * from product where pid = 1;查询pid<>1的商品(!=)select * from product where pid <> 1;查询价格在3000到6000之间的商品select * from product where price between 3000 and 6000;查询pid在1,5,7,15范围内的商品select * from product where id = 1; select * from product where id = 5; select * from product where id = 7; select * from product where id = 15; select * from product where id in (1,5,7,15);查询商品名以iPho开头的商品(iPhone系列)select * from product where pname like 'iPho%';查询商品价格大于3000并且数量大于20的商品 (条件 and 条件 and…)select * from product where price > 3000 and num > 20;查询id=1或者价格小于3000的商品select * from product where pid = 1 or price < 3000;5.4 排序查询排序是写在查询的后面,代表把数据查询出来之后再排序5.4.1 环境的准备# 创建学生表(有sid,学生姓名,学生性别,学生年龄,分数列,其中sid为主键自动增长) CREATE TABLE student( sid INT PRIMARY KEY auto_increment, sname VARCHAR(40), sex VARCHAR(10), age INT, score DOUBLE ); INSERT INTO student VALUES(null,'zs','男',18,98.5); INSERT INTO student VALUES(null,'ls','女',18,96.5); INSERT INTO student VALUES(null,'ww','男',15,50.5); INSERT INTO student VALUES(null,'zl','女',20,98.5); INSERT INTO student VALUES(null,'tq','男',18,60.5); INSERT INTO student VALUES(null,'wb','男',38,98.5); INSERT INTO student VALUES(null,'小丽','男',18,100); INSERT INTO student VALUES(null,'小红','女',28,28); INSERT INTO student VALUES(null,'小强','男',21,95);5.4.2 单列排序语法: 只按某一个字段进行排序,单列排序SELECT 字段名 FROM 表名 [WHERE 条件] ORDER BY 字段名 [ASC|DESC]; //ASC: 升序,默认值; DESC: 降序案例: 以分数降序查询所有的学生SELECT * FROM student ORDER BY score DESC5.4.3 组合排序语法: 同时对多个字段进行排序,如果第1个字段相等,则按第2个字段排序,依次类推SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名1 [ASC|DESC], 字段名2 [ASC|DESC];练习: 以分数降序查询所有的学生, 如果分数一致,再以age降序SELECT * FROM student ORDER BY score DESC, age DESC5.5 聚合函数聚合函数用于统计,通常会和分组查询一起使用,用于统计每组的数据5.5.1 聚合函数列表聚合函数 作用max(列名) 求这一列的最大值min(列名) 求这一列的最小值avg(列名) 求这一列的平均值count(列名) 统计这一列有多少条记录sum(列名) 对这一列求总和语法SELECT 聚合函数(列名) FROM 表名 [where 条件];案例-- 求出学生表里面的最高分数 SELECT MAX(score) FROM student -- 求出学生表里面的最低分数 SELECT MIN(score) FROM student -- 求出学生表里面的分数的总和(忽略null值) SELECT SUM(score) FROM student -- 求出学生表里面的平均分 SELECT AVG(score) FROM student -- 求出学生表里面的平均分(缺考了当成0分处理) SELECT AVG(IFNULL(score,0)) FROM student -- 统计学生的总人数 (忽略null) SELECT COUNT(sid) FROM student SELECT COUNT(*) FROM student注意: 聚合函数会忽略空值NULL我们发现对于NULL的记录不会统计,建议如果统计个数则不要使用有可能为null的列,但如果需要把NULL也统计进去呢?我们可以通过 IFNULL(列名,默认值) 函数来解决这个问题. 如果列不为空,返回这列的值。如果为NULL,则返回默认值。-- 求出学生表里面的平均分(缺考了当成0分处理) SELECT AVG(IFNULL(score,0)) FROM student5.6 分组查询GROUP BY将分组字段结果中相同内容作为一组,并且返回每组的第一条数据,所以单独分组没什么用处。分组的目的就是为了统计,一般分组会跟聚合函数一起使用5.6.1分组语法SELECT 字段1,字段2... FROM 表名 [where 条件] GROUP BY 列 [HAVING 条件];案例-- 根据性别分组, 统计每一组学生的总人数 SELECT sex '性别',COUNT(sid) '总人数' FROM student GROUP BY sex -- 根据性别分组,统计每组学生的平均分 SELECT sex '性别',AVG(score) '平均分' FROM student GROUP BY sex -- 根据性别分组,统计每组学生的总分 SELECT sex '性别',SUM(score) '总分' FROM student GROUP BY sex5.6.2 分组后筛选 having分组后的条件,不能写在where之后,where关键字要写在group by之前根据性别分组, 统计每一组学生的总人数> 5的(分组后筛选)SELECT sex, count(*) FROM student GROUP BY sex HAVING count(sid) > 5根据性别分组,只统计年龄大于等于18的,并且要求组里的人数大于4SELECT sex '性别',COUNT(sid) '总人数' FROM student WHERE age >= 18 GROUP BY sex HAVING COUNT(sid) > 45.6.3 where和having的区别【面试】子名 作用where 子句 1) 对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,即先过滤再分组。2) where后面不可以使用聚合函数having字句 1) having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,即先分组再过滤。2) having后面可以使用聚合函数5.7 分页查询5.7.1 语法select ... from .... limit a ,bLIMIT a,b;a 表示的是跳过的数据条数b 表示的是要查询的数据条数5.7.2 案例-- 分页查询 -- limit 关键字是使用在查询的后边,如果有排序的话则使用在排序的后边 -- limit的语法: limit offset,length 其中offset表示跳过多少条数据,length表示查询多少条数据 SELECT * FROM product LIMIT 0,3 -- 查询product表中的前三条数据(0表示跳过0条,3表示查询3条) SELECT * FROM product LIMIT 3,3 -- 查询product表的第四到六条数据(3表示跳过3条,3表示查询3条) -- 分页的时候,只会告诉你我需要第几页的数据,并且每页有多少条数据 -- 假如,每页需要3条数据,我想要第一页数据: limit 0,3 -- 假如,每页需要3条数据,我想要第二页数据: limit 3,3 -- 假如,每页需要3条数据,我想要第三页数据: limit 6,3 -- 结论: length = 每页的数据条数,offset = (当前页数 - 1)*每页数据条数 -- limit (当前页数 - 1)*每页数据条数, 每页数据条数5.8 查询的语法小结select...from...where...group by...order by...limit select...from...where... select...from...where...order by... select...from...where...limit... select...from...where...order by...imit第六章 数据库三范式好的数据库设计对数据的存储性能和后期的程序开发,都会产生重要的影响。建立科学的,规范的数据库就需要满足一些规则来优化数据的设计和存储,这些规则就称为范式。6.1 第一范式: 确保每列保持原子性第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就说明该数据库表满足了第一范式。第一范式的合理遵循需要根据系统的实际需求来定。比如某些数据库系统中需要用到“地址”这个属性,本来直接将“地址”属性设计成一个数据库表的字段就行。但是如果系统经常会访问“地址”属性中的“城市”部分,那么就非要将“地址”这个属性重新拆分为省份、城市、详细地址等多个部分进行存储,这样在对地址中某一部分操作的时候将非常方便。这样设计才算满足了数据库的第一范式,如下表所示。如果不遵守第一范式,查询出数据还需要进一步处理(查询不方便)。遵守第一范式,需要什么字段的数据就查询什么数据(方便查询)6.2 第二范式: 确保表中的每列都和主键相关第二范式在第一范式的基础之上更进一层。第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。也就是说在一个数据库表中,一个表中只能保存一种数据,不可以把多种数据保存在同一张数据库表中。比如要设计一个订单信息表,因为订单中可能会有多种商品,所以要将订单编号和商品编号作为数据库表的联合主键,如下表所示这样就产生一个问题:这个表中是以订单编号和商品编号作为联合主键。这样在该表中商品名称、单位、商品价格等信息不与该表的主键相关,而仅仅是与商品编号相关。所以在这里违反了第二范式的设计原则。而如果把这个订单信息表进行拆分,把商品信息分离到另一个表中,把订单项目表也分离到另一个表中,就非常完美了。如下所示<img src="imgs/tu_13.png" style="zoom: 67%;" />这样设计,在很大程度上减小了数据库的冗余。如果要获取订单的商品信息,使用商品编号到商品信息表中查询即可6.3 第三范式: 确保每列都和主键列直接相关,而不是间接相关第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。比如在设计一个订单数据表的时候,可以将客户编号作为一个外键和订单表建立相应的关系。而不可以在订单表中添加关于客户其它信息(比如姓名、所属公司等)的字段。如下面这两个表所示的设计就是一个满足第三范式的数据库表。<img src="imgs/tu_14.png" style="zoom:67%;" />这样在查询订单信息的时候,就可以使用客户编号来引用客户信息表中的记录,也不必在订单信息表中多次输入客户信息的内容,减小了数据冗余第七章 外键约束7.1 外键约束的概念在遵循三范式的前提下,很多时候我们必须要进行拆表,将数据分别存放在多张表中,以减少冗余数据。但是拆分出来的表与表之间是有着关联关系的,我们必须得通过一种约束来约定表与表之间的关系,这种约束就是外键约束7.2 外键约束的作用外键约束是保证一个或两个表之间的参照完整性,外键是构建于一个表的两个字段或是两个表的两个字段之间的参照关系。7.3 创建外键约束的语法7.3.1 在建表时指定外键约束create table [数据名.]从表名( 字段名1 数据类型 primary key , 字段名2 数据类型 , ...., [constraint 外键约束名] foreign key (从表字段) references 主表名(主表字段) [on update 外键约束等级][on delete 外键约束等级] #外键只能在所有字段列表后面单独指定 #如果要自己命名外键约束名,建议 主表名_从表名_关联字段名_fk );7.3.2 在建表后指定外键约束alter table 从表名称 add [constraint 外键约束名] foreign key (从表字段名) references 主表名(主表被参照字段名) [on update xx][on delete xx];7.4 删除外键约束的语法ALTER TABLE 表名称 DROP FOREIGN KEY 外键约束名; #查看约束名 SELECT * FROM information_schema.table_constraints WHERE table_name = '表名称'; #删除外键约束不会删除对应的索引,如果需要删除索引,需要用ALTER TABLE 表名称 DROP INDEX 索引名; #查看索引名 show index from 表名称;7.5 外键约束的要求在从表上建立外键,而且主表要先存在。一个表可以建立多个外键约束通常情况下,从表的外键列一定要指向主表的主键列从表的外键列与主表被参照的列名字可以不相同,但是数据类型必须一样7.6 外键约束等级Cascade方式:在主表上update/delete记录时,同步update/delete掉从表的匹配记录Set null方式:在主表上update/delete记录时,将从表上匹配记录的列设为null,但是要注意子表的外键列不能为not nullNo action方式:如果子表中有匹配的记录,则不允许对父表对应候选键进行update/delete操作Restrict方式:同no action, 都是立即检查外键约束Set default方式(在可视化工具SQLyog中可能显示空白):父表有变更时,子表将外键列设置成一个默认的值,但Innodb不能识别如果没有指定等级,就相当于Restrict方式7.7 外键约束练习-- 部门表 create table dept( id int primary key, dept_name varchar(50), dept_location varchar(50) ); -- 员工表 CREATE TABLE emp( eid int primary key, name varchar(50) not null, sex varchar(10), dept_id int ); -- 给员工表表的dept_id添加外键指向部门表的主键 alter table emp add foreign key(dept_id) references dept(id)第八章 多表间关系8.1 一对多关系8.1.1 概念一对多的关系是指: 主表的一行数据可以同时对应从表的多行数据,反过来就是从表的多行数据指向主表的同一行数据。8.1.2 应用场景分类表和商品表、班级表和学生表、用户表和订单表等等8.1.2 建表原则将一的一方作为主表,多的一方作为从表,在从表中指定一个字段作为外键,指向主表的主键8.1.3 建表语句练习-- 创建分类表 CREATE TABLE category( cid INT PRIMARY KEY AUTO_INCREMENT, cname VARCHAR(50) ); -- 创建商品表 CREATE TABLE product( pid INT PRIMARY KEY AUTO_INCREMENT, pname VARCHAR(50), price DOUBLE, cid INT ) -- 给商品表添加一个外键 alter table product add foreign key(cid) references category(cid)8.2 多对多关系8.2.1 概念两张表都是多的一方,A表的一行数据可以同时对应B表的多行数据,反之B表的一行数据也可以同时对应A表的多行数据8.2.2 应用场景订单表和商品表、学生表和课程表等等8.2.3 建表原则因为两张表都是多的一方,所以在两张表中都无法创建外键,所以需要新创建一张中间表,在中间表中定义两个字段,这俩字段分别作为外键指向两张表各自的主键8.2.4 建表语句练习-- 创建学生表 CREATE TABLE student( sid INT PRIMARY KEY AUTO_INCREMENT, sname VARCHAR(50) ); -- 创建课程表 CREATE TABLE course( cid INT PRIMARY KEY AUTO_INCREMENT, cname VARCHAR(20) ); -- 创建中间表 CREATE TABLE s_c_table( sno INT, cno INT ); -- 给sno字段添加外键指向student表的sid主键 ALTER TABLE s_c_table ADD CONSTRAINT fkey01 FOREIGN KEY(sno) REFERENCES student(sid); -- 给cno字段添加外键指向course表的cid主键 ALTER TABLE s_c_table ADD CONSTRAINT fkey03 FOREIGN KEY(cno) REFERENCES course(cid);8.3 一对一关系(了解)8.3.1 第一种一对一关系我们之前学习过一对多关系,在一对多关系中主表的一行数据可以对应从表的多行数据,反之从表的一行数据则只能对应主表的一行数据。这种一行数据对应一行数据的关系,我们可以将其看作一对一关系3.3.2 第二种一对一关系A表中的一行数据对应B表中的一行数据,反之B表中的一行数据也对应A表中的一行数据,此时我们可以将A表当做主表B表当做从表,或者是将B表当做主表A表当做从表建表原则在从表中指定一个字段创建外键并指向主表的主键,然后给从表的外键字段添加唯一约束第九章 多表关联查询多表关联查询是使用一条SQL语句,将关联的多张表的数据查询出来9.1 环境准备-- 创建一张分类表(类别id,类别名称.备注:类别id为主键并且自动增长)CREATE TABLE t_category( cid INT PRIMARY KEY auto_increment, cname VARCHAR(40) ); INSERT INTO t_category values(null,'手机数码'); INSERT INTO t_category values(null,'食物'); INSERT INTO t_category values(null,'鞋靴箱包'); -- 创建一张商品表(商品id,商品名称,商品价格,商品数量,类别.备注:商品id为主键并且自动增长) CREATE TABLE t_product( pid INT PRIMARY KEY auto_increment, pname VARCHAR(40), price DOUBLE, num INT, cno INT ); insert into t_product values(null,'苹果电脑',18000,10,1); insert into t_product values(null,'iPhone8s',5500,100,1); insert into t_product values(null,'iPhone7',5000,100,1); insert into t_product values(null,'iPhone6s',4500,1000,1); insert into t_product values(null,'iPhone6',3800,200,1); insert into t_product values(null,'iPhone5s',2000,10,1); insert into t_product values(null,'iPhone4s',18000,1,1); insert into t_product values(null,'方便面',4.5,1000,2); insert into t_product values(null,'咖啡',10,100,2); insert into t_product values(null,'矿泉水',2.5,100,2); insert into t_product values(null,'法拉利',3000000,50,null); -- 给 商品表添加外键 ALTER TABLE t_product ADD FOREIGN KEY(cno) REFERENCES t_category(cid); 9.2 交叉查询【了解】交叉查询其实就是将多张表的数据没有条件地连接在一起进行展示9.2.1 语法select a.列,a.列,b.列,b.列 from a,b ; select a.*,b.* from a,b ; --或者 select * from a,b;9.2.2 练习使用交叉查询类别和商品select * from t_category,t_product;通过查询结果我们可以看到,交叉查询其实是一种错误的做法,在查询到的结果集中有大量的错误数据,我们称交叉查询到的结果集是笛卡尔积9.2.3 笛卡尔积假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。9.3 内连接查询交叉查询产生这样的结果并不是我们想要的,那么怎么去除错误的、不想要的记录呢,当然是通过条件过滤。通常要查询的多个表之间都存在关联关系,那么就通过关联关系(主外键关系)去除笛卡尔积。这种通过条件过滤去除笛卡尔积的查询,我们称之为连接查询。连接查询又可以分为内连接查询和外连接查询,我们先学习内连接查询9.3.1 隐式内连接查询隐式内连接查询里面是没有inner join关键字select [字段,字段,字段] from a,b where 连接条件 (b表里面的外键 = a表里面的主键 ) 9.3.2 显式内连接查询显式内连接查询里面是有inner join关键字select [字段,字段,字段] from a [inner] join b on 连接条件 [ where 其它条件]9.3.3 内连接查询练习查询所有类别下的商品信息,如果该类别下没有商品则不展示-- 1 隐式内连接方式 select *from t_category c, t_product p WHERE c.cid = p.cno; -- 2 显示内连接方式 -- 查询手机数码这个分类下的所有商品的信息以及分类信息 SELECT * FROM t_product tp INNER JOIN t_category tc ON tp.cno = tc.cid WHERE tc.cname = '手机数码'; SELECT * from t_category c INNER JOIN t_product p ON c.cid = p.cno9.3.4 内连接查询的特点主表和从表中的数据都是满足连接条件则能够查询出来,不满足连接条件则不会查询出来9.4 外连接查询我们发现内连接查询出来的是满足连接条件的公共部分, 如果要保证查询出某张表的全部数据情况下进行连接查询. 那么就要使用外连接查询了. 外连接分为左外连接和右外连接9.4.1 左外连接查询9.4.1.1 概念以join左边的表为主表,展示主表的所有数据,根据条件查询连接右边表的数据,若满足条件则展示,若不满足则以null显示。可以理解为:在内连接的基础上保证左边表的数据全部显示9.4.1.2 语法select 字段 from a left [outer] join b on 条件9.4.1.3 练习查询所有类别下的商品信息,就算该类别下没有商品也需要将该类别的信息展示出来SELECT * FROM t_category c LEFT OUTER JOIN t_product p ON c.cid = p.cno9.4.2 右外连接查询9.4.2.1 概念以join右边的表为主表,展示右边表的所有数据,根据条件查询join左边表的数据,若满足则展示,若不满足则以null显示。可以理解为:在内连接的基础上保证右边表的数据全部显示9.4.2.2 语法select 字段 from a right [outer] join b on 条件9.4.2.3 练习查询所有商品所对应的类别信息SELECT * FROM t_category c RIGHT OUTER JOIN t_product p ON c.cid = p.cno9.5 union联合查询实现全外连接查询首先要明确,联合查询不是多表连接查询的一种方式。联合查询是将多条查询语句的查询结果合并成一个结果并去掉重复数据。全外连接查询的意思就是将左表和右表的数据都查询出来,然后按照连接条件连接9.5.1 union的语法查询语句1 union 查询语句2 union 查询语句3 ...9.5.2 练习# 用左外的A union 右外的B SELECT * FROM t_category c LEFT OUTER JOIN t_product p ON c.cid = p.cno union SELECT * FROM t_category c RIGHT OUTER JOIN t_product p ON c.cid = p.cno9.6 自连接查询自连接查询是一种特殊的多表连接查询,因为两个关联查询的表是同一张表,通过取别名的方式来虚拟成两张表,然后进行两张表的连接查询9.6.1 准备工作-- 员工表 CREATE TABLE emp ( id INT PRIMARY KEY, -- 员工id ename VARCHAR(50), -- 员工姓名 mgr INT , -- 上级领导 joindate DATE, -- 入职日期 salary DECIMAL(7,2) -- 工资 ); -- 添加员工 INSERT INTO emp(id,ename,mgr,joindate,salary) VALUES (1001,'孙悟空',1004,'2000-12-17','8000.00'), (1002,'卢俊义',1006,'2001-02-20','16000.00'), (1003,'林冲',1006,'2001-02-22','12500.00'), (1004,'唐僧',1009,'2001-04-02','29750.00'), (1005,'李逵',1006,'2001-09-28','12500.00'), (1006,'宋江',1009,'2001-05-01','28500.00'), (1007,'刘备',1009,'2001-09-01','24500.00'), (1008,'猪八戒',1004,'2007-04-19','30000.00'), (1009,'罗贯中',NULL,'2001-11-17','50000.00'), (1010,'吴用',1006,'2001-09-08','15000.00'), (1011,'沙僧',1004,'2007-05-23','11000.00'), (1012,'李逵',1006,'2001-12-03','9500.00'), (1013,'小白龙',1004,'2001-12-03','30000.00'), (1014,'关羽',1007,'2002-01-23','13000.00'); #查询孙悟空的上级 SELECT employee.*,manager.ename mgrname FROM emp employee,emp manager where employee.mgr=manager.id AND employee.ename='孙悟空'9.6.2 自连接查询练习查询员工的编号,姓名,薪资和他领导的编号,姓名,薪资#这些数据全部在员工表中 #把t_employee表,即当做员工表,又当做领导表 #领导表是虚拟的概念,我们可以通过取别名的方式虚拟 SELECT employee.id "员工的编号",emp.ename "员工的姓名" ,emp.salary "员工的薪资", manager.id "领导的编号" ,manager.ename "领导的姓名",manager.salary "领导的薪资" FROM emp employee INNER JOIN emp manager #emp employee:employee.,表示的是员工表的 #emp manager:如果用manager.,表示的是领导表的 ON employee.mgr = manager.id # 员工的mgr指向上级的id #表的别名不要加"",给列取别名,可以用"",列的别名不使用""也可以,但是要避免包含空格等特殊符号。第十章 子查询如果一个查询语句嵌套在另一个查询语句里面,那么这个查询语句就称之为子查询,根据位置不同,分为:where型,from型,exists型。注意:不管子查询在哪里,子查询必须使用()括起来。10.1 where型①子查询是单值结果(单行单列),那么可以对其使用(=,>等比较运算符)# 查询价格最高的商品信息 select * from t_product where price = (select max(price) from t_product)②子查询是多值结果,那么可对其使用(【not】in(子查询结果),或 >all(子查询结果),或>=all(子查询结果),<all(子查询结果),<=all(子查询结果),或 >any(子查询结果),或>=any(子查询结果),<any(子查询结果),<=any(子查询结果))# 查询价格最高的商品信息 SELECT * FROM t_product WHERE price >=ALL(SELECT price FROM t_product) select * from t_product order by price desc limit 0,110.2 from型子查询的结果是多行多列的结果,类似于一张表格。必须给子查询取别名,即临时表名,表的别名不要加“”和空格。-- 思路一: 使用连接查询 -- 使用外连接,查询出分类表的所有数据 SELECT tc.cname,COUNT(tp.pid) FROM t_category tc LEFT JOIN t_product tp ON tp.cno = tc.cid GROUP BY tc.cname -- 思路二: 使用子查询 -- 第一步:对t_product根据cno进行分组查询,统计每个分类的商品数量 SELECT cno,COUNT(pid) FROM t_product GROUP BY cno -- 第二步: 用t_category表去连接第一步查询出来的结果,进行连接查询,此时要求查询出所有的分类 SELECT tc.cname,IFNULL(tn.total,0) '总数量' FROM t_category tc LEFT JOIN (SELECT cno,COUNT(pid) total FROM t_product GROUP BY cno) tn ON tn.cno=tc.cid10.3 exists型# 查询那些有商品的分类 SELECT cid,cname FROM t_category tc WHERE EXISTS (SELECT * FROM t_product tp WHERE tp.cno = tc.cid);
2024年02月05日
17 阅读
0 评论
0 点赞
2024-01-04
结合 PHP 和 Python 开发灵活高性能的移动应用程序
结合 PHP 和 Python 开发灵活高性能的移动应用程序踏上移动应用开发之旅,如同扬帆起航,驶向广阔的数字海洋。在这个快节奏的世界中,用户体验至关重要,编程语言的选择是开发人员成功的关键。在这篇文章中,我们将探讨 PHP 和 Python 的强强联手——这两种编程语言在协同工作时可以构建可扩展、高效且用户友好的移动应用程序。让我们一起探索制作移动应用程序的艺术,让您的应用程序满足甚至超越现代用户的期望。PHP 在移动应用程序开发中的应用PHP(超文本预处理器)作为一种广泛使用的开源脚本语言而脱颖而出,以其多功能性和用户友好性而闻名。PHP 通常被认为是 Web 开发语言,但其功能远不止于此。让我们来探讨一下 PHP 在移动应用程序开发中的价值所在:后端开发卓越PHP 凭借其强大的功能,在移动应用程序的服务器端逻辑开发方面表现出色。它能够熟练地处理复杂的数据处理、无缝的数据库交互和安全的用户身份验证。其与各种数据库的兼容性,使其成为强大且可靠的后端解决方案。无缝整合PHP 具有强大的集成能力,可以轻松地与各种技术和 API 进行集成。这使您能够将移动应用程序无缝连接到第三方服务,例如支付网关、社交媒体平台和云服务。这种连接可以增强应用程序的功能,为您的用户提供丰富的体验。可扩展性是其核心PHP 的可扩展性是众所周知的特性。随着您的移动应用程序越来越受欢迎,流量也随之激增。PHP 具有良好的扩展性,能够应对使用量的激增。通过正确构建应用程序并优化其性能,您可以确保应用程序即使在高需求时期也能保持响应灵敏且可靠。社区支持PHP 拥有庞大而活跃的开发者社区,为您提供了丰富的资源、库和框架,可以帮助您加快开发速度并克服项目挑战。该社区的集体知识和支持是您宝贵的财富。具有成本效益的开发PHP 作为开源语言,无需购买授权费用,可大幅降低开发成本。这对于初创公司和小型企业等资源有限的组织尤为有利。PHP 允许您构建功能丰富的应用程序,而无需投入大量资金。Python 移动应用程序开发Python 作为编程语言的另一强者,在移动应用程序开发领域具有重要影响力。Python 因其简单性和可读性而闻名,在制作移动应用程序时具有以下几个优势:跨平台开发能力Python 的多功能性体现在其促进跨平台移动应用程序开发的能力。使用单个代码库,您可以无缝部署到多个平台,例如 iOS 和 Android。与创建多个独立应用程序相比,这种方法可简化开发并节省时间和精力。丰富的库和框架生态系统Python 为移动应用程序开发提供了丰富的库和框架生态系统,如 Kivy 和 BeeWare。这些工具使开发人员能够创建功能丰富且具有视觉吸引力的应用程序。机器学习集成Python 是开发需要机器学习功能的移动应用程序的理想选择。TensorFlow 和 PyTorch 等库可轻松将人工智能和机器学习功能集成到应用程序中,从而为创新创造了巨大的潜力。用户界面 (UI) 设计灵活性Python 的丰富 UI 设计选项使您能够创建令人惊叹的、用户友好的界面。Kivy 和 Tkinter 等库提供了广泛的 UI 自定义功能,使您能够完全控制应用程序的外观和感觉。快速发展Python 干净的语法和简单性加速了应用程序开发过程。当时间紧迫,需要快速推出移动应用程序以满足市场需求和抓住机遇时,这尤为有利。结合 PHP 和 Python 以实现最大效率虽然 PHP 和 Python 各自具有独特的优势,但它们也可以在移动应用程序开发领域完美地互补。以下是如何战略性地结合这两种强大的语言:后端-前端协同一种可行的战略是将后端逻辑使用 PHP 实现,将前端开发使用 Python 实现。这种清晰的职责分离可以带来代码库的清晰性和开发工作流程的高效性。API集成和谐PHP 擅长管理 API 集成和服务器端操作,Python 则负责用户界面和客户端功能。这种明确的职责分工,确保了流畅、无缝的用户体验。跨平台兼容性考虑跨平台开发?Python 是创建 iOS 和 Android 前端的理想选择,而 PHP 则负责后端。这种方法简化了开发和维护,因为您只需维护一个代码库即可部署到多个平台。可扩展性和性能协同PHP 的可扩展性和性能能力与 Python 的简单性和快速开发能力相结合,可以成为一个成功的组合。PHP 可以处理可扩展性和性能方面的问题,而 Python 可以加速初始开发阶段,使您能够快速响应市场需求。借助 PHP 和 Python 的动态组合,两种语言的独特优势得以和谐融合,充分发挥各自的潜力。这种协作方式能够确保移动应用程序能够满足现代用户需求的复杂性,同时提供简洁、响应的用户体验。
2024年01月04日
15 阅读
0 评论
0 点赞
2024-01-04
PHP开发:常见功能实现与优化建议
PHP开发:常见功能实现与优化建议随着互联网的快速发展,PHP作为一种广泛应用的Web开发语言,被越来越多的开发者所使用。在PHP开发过程中,常见的功能实现与优化是开发者需要重点关注的问题。本文将讨论一些常见的PHP功能实现以及优化建议,帮助开发者提升项目质量和性能。用户认证与授权在Web应用开发中,用户的认证与授权是一个至关重要的功能。PHP提供了一些内置的函数和类可以用于实现用户认证与授权,如session、cookie、password_hash等。合理使用这些功能,可以确保用户的信息安全,并提供个性化的用户体验。在实现用户认证时,建议使用密码哈希函数password_hash()来存储用户密码。这样可以确保用户密码的安全性,防止密码泄露导致的风险。在授权时,建议使用RBAC(Role-Based Access Control)模型来管理用户权限。RBAC模型可以将用户分为不同的角色,并为每个角色分配相应的权限。这样可以灵活地控制用户对不同功能模块的访问权限。数据库操作与优化在Web应用中,与数据库的交互是非常频繁的。因此,对数据库操作的性能优化是非常重要的。合理使用索引可以提升数据库查询的性能。在设计数据库表结构时,根据查询的频率和字段的关联性,选择合适的字段作为索引。同时,避免在查询条件中使用不必要的函数或操作符,以减少数据库的负担。对于频繁查询的数据,可以使用缓存来提升访问速度。PHP提供了多种缓存技术,如Memcache、Redis等。使用缓存可以减少对数据库的访问次数,提高系统的响应速度。另外,通过合理使用数据库连接池和数据库连接复用,可以减少数据库连接的创建和关闭的开销,提升系统的性能。文件上传与处理在Web应用中,文件上传是一个常见的功能。对于文件上传,需要注意安全性和性能方面的优化。对于上传的文件,应该进行安全检查,包括文件类型、大小以及文件内容的合法性。避免上传恶意文件或大文件导致系统资源耗尽。文件上传后的处理也是需要考虑的问题。对于图片文件,可以使用图像处理库对图片进行缩放、剪裁等操作,从而适应不同的展示需求。对于其他类型的文件,可以根据业务需求进行处理和存储。在文件上传时,还要合理设置文件的保存路径和文件名,以避免同名文件覆盖或文件数量过多导致的管理问题。前端与后端的交互前端与后端的交互是Web开发中的重要环节。合理使用AJAX可以减少页面的刷新次数,提高用户体验。在PHP开发中,可以使用jQuery等前端框架来简化AJAX的操作,实现异步加载数据。同时,在后端代码中,使用合适的数据格式来传输数据,如JSON、XML等。这样可以减少数据的传输量,提高通信效率。对于前端资源的合并和压缩也是一种优化手段。合并和压缩前端资源可以减少HTTP请求的次数,提高页面加载速度。错误处理与日志记录在PHP开发中,错误处理和日志记录是非常重要的。良好的错误处理和日志记录可以帮助开发者及时发现并解决问题。在错误处理方面,建议使用try-catch语句来捕获和处理异常。同时,根据业务需求,可以自定义异常类来实现更加灵活的异常处理。在日志记录方面,可以使用相关的日志库,如Monolog。通过日志记录,可以追踪代码的执行过程,对于异常情况可以提供有用的调试信息,帮助快速定位问题并进行修复。PHP开发中常见功能的实现与优化是开发者需要关注的问题。通过合理使用PHP提供的功能和技术,可以提升项目的质量和性能。同时,不断学习和探索最新的开发技术,也能够帮助开发者不断提升自己的开发水平。
2024年01月04日
8 阅读
0 评论
0 点赞
2024-01-04
PHP 枚举:是时候告别老式类常量了
PHP 枚举:是时候告别老式类常量了枚举在 PHP 中已经引入两年了,如果您还在使用类常量来表示枚举值,那么是时候切换到 PHP 枚举了。以下是四个令人信服的理由。1、内置“cases”方法想象一下,您正在开发一个具有不同用户状态的项目。有些是活跃的,有些是禁止的,还有一些尚未完成注册。以老式的方式,您可以使用类常量处理这些状态,从而产生如下代码:all方法之所以存在,是因为它满足了一个非常常见的需求:在下拉菜单中显示所有可能的选项。您可以通过创建自己的方法或使用反射来实现这一点。现在,让我们看看枚举如何简化这一过程:使用枚举,您可以使用内置的“cases”方法,它会自动返回所有可用选项的数组。告别每次添加新状态时手动更新常用选项列表。2、类型提示回到用户状态的示例,让我们考虑一种情况,我们有一种设置用户状态的方法。我们希望只将有效状态存储在数据库中。它通常是这样的:看起来有点难看。我们有更好的解决方案!通过类型提示,我们可以确保只有来自 UserStatus 枚举的有效状态值才能传递给方法参数。这可以消除潜在的错误,例如使用无效状态值引起的问题。3、枚举方法我将继续使用带有用户状态的示例。假设有些人可以登录系统,有些人则不能。老式的方式:使用枚举:虽然它不是“游戏规则改变者”,但它确实可以使代码更简洁、更紧凑。4、独特性这个与本主文的第二点略有重叠,但我想单独强调一下。想象一下,我们不仅有用户的状态,还有我们在线商店中商品的状态。让我们从前面的示例中获取一段代码,并以不当的方式使用它。虽然我们不会收到错误,但这可能是一个潜在的问题。如果将来我们更改 ProductStatus::ACTIVE 常量的值,我们可能会在这里收到错误。那么枚举呢?枚举是唯一的。即使 UserStatus::ACTIVE 和 ProductStatus::ACTIVE 具有相同的值,它也是不同的项目。我们可以轻松地手动检查。这意味着类型提示对我们有双重帮助——它不允许使用不正确的值,也不允许使用这些值的不正确来源,即使它们看起来合适。
2024年01月04日
7 阅读
0 评论
0 点赞
2024-01-04
PHP底层的高效代码调试与实用工具
PHP底层的高效代码调试与实用工具PHP是一种流行的服务器端编程语言,已经成为许多网站和应用程序的核心。在开发和调试PHP时,需要使用一些工具和技术来提高代码的效率和质量。本文将重点介绍PHP底层的高效代码调试和实用工具,并提供具体的代码示例。XdebugXdebug是PHP调试器的一种扩展,可用于追踪代码执行过程中的变量、函数和方法。它支持多种IDE(集成开发环境)和编辑器,例如Eclipse、Zend Studio和NetBeans。Xdebug可以帮助开发人员快速诊断和修复代码中的问题。以下是一个示例:<?php function my_fun($x, $y) { $result = $x + $y; return $result; } echo my_fun(2, 3);如果想要追踪函数my_fun中的变量和结果,可以使用Xdebug的函数追踪功能。在php.ini文件中启用Xdebug扩展,并将追踪输出设置为html:xdebug.trace_format = 1 xdebug.trace_output_name = "trace.%c" xdebug.trace_output_dir = "/tmp"然后运行脚本,并访问生成的追踪文件:http://localhost/trace.1234PHPDBGPHPDBG是PHP的一个交互式调试器,可用于快速查找和修复代码中的错误。它支持设置断点、单步执行、变量查看和追踪执行流程。以下是一个示例:<?php function my_fun($x, $y) { $result = $x + $y; return $result; } echo my_fun(2, 3);如果想要在my_fun函数中设置断点,可以使用break命令:break my_fun然后运行脚本,并执行以下命令:run -d memory_limit=256M script.php在程序运行到断点时,可以使用step命令单步执行代码,或使用watch命令查看变量:watch $resultBlackfireBlackfire是一个针对PHP应用程序的性能分析工具,可用于识别性能瓶颈并提供优化建议。它支持在开发、测试和生产环境中使用,并提供丰富的性能指标和图表。以下是一个示例:<?php function my_fun($x, $y) { $result = $x + $y; return $result; } echo my_fun(2, 3);如果想要测试my_fun函数的性能,可以使用Blackfire扩展并运行此代码段:blackfire run php script.php然后在Blackfire控制台中查看性能报告和分析结果。可以查看函数调用时间、内存占用情况和I/O操作的统计数据。总结本文介绍了PHP底层的高效代码调试和实用工具,包括Xdebug、PHPDBG和Blackfire。这些工具可以帮助开发人员快速定位和修复代码中的问题,提高代码的效率和质量。
2024年01月04日
9 阅读
0 评论
0 点赞
1
2
3
4
...
112