数据库
数据库介绍
数据库本质也是一个文件,存储数据用.通过标准的sql语句可以操作数据库.增删改查(CRUD)
C Create 创建
R Read或者Retrieve 查询
U Update 更新
D Delete 删除
数据库管理系统(DataBase Management System,简写dbms)称为数据库,大白话就是我们安装的软件
关系型数据库:
大白话存放实体与实体之间关系的数据库
实体:用户 订单 商品
关系:用户<拥有>订单 订单<包含>商品
常见的关系型数据库:
数据库名称 厂商 特点
oracle oracle 收费的大型的数据库软件
sqlserver 微软 收费的大型的数据库软件 可视化操作
sybase sybase
DB2 IBM 收费的大型的数据库软件
mysql oracle 中小型的数据库.
安装了服务器软件之后,启动服务,计算机就被称之为数据库服务器.
可以创建数据库.在数据库的基础之上创建表.就可以在表上进行crud
java
类===>表
对象===>记录(行)
属性====>字段(列)
mysql的安装
安装目录:
存放英文目录,不带空格的目录
把软件和数据文件目录放到一起
端口号:3306
用户名:root
密码和重复密码:root
服务名称:MySql
启动服务的方式:
1.计算机右键管理
2.在运行中输入services.msc
3.在cmd窗口中 通过命令启动
net start mysql
停止命令
net stop mysql
若出现拒绝访问5:请使用管理员权限运行cmd窗口即可
mysql的登录:
在cmd窗口中:
格式1:mysql -uroot -p密码 回车
格式2:mysql -uroot -p 回车
在输入密码
格式3:mysql -hip地址 -uroot -p密码 回车
密码的重置:
前提:保证mysql服务关闭
步骤:
1.在cmd窗口中输入 mysqld --console --skip-grant-tables
2.再次打开一个cmd窗口 输入 mysql -uroot
3.切换数据库 use mysql;
4.修改密码 update user set password=password('新密码') where user='root';
5.关闭两个cmd窗口,启动mysql服务
////////////////////////////////////////////
sql:
结构化查询语言(Structured Query Language),是一种数据库查询和程序设计语言,用于存取、查询、更新数据以及管理关系数据库系统.
分类:
DDL:数据库定义语言
操作对象:数据库和表
关键词:create alter drop
操作数据库:
创建(☆)
格式:create database 数据库名称;
例如:create database day05;
扩展:
格式:create database 数据库名称 character set 字符集 [collate 校对规则];
例如:create database day0501 character set gbk;
修改
就是修改数据库的字符集或者校对规则
格式:alter database 数据库名称 character set 新的字符集 [collate 新的校对规则]
例如:
alter database day0501 character set utf8;
删除
格式:
drop database 数据库名称;
例如:
drop database day0501;
常用命令:
查看所有的数据库:show databases;
查看建库语句:show create database 数据库名称;
-- 查看字符集和默认的校对规则:show character set;
操作表:
创建表:
格式:
create table 表名(
字段描述1,
字段描述2,
字段描述3,
..
字段描述n
);
字段描述的格式: 字段名 字段类型 [约束]
例如:
create table user(
id int,
name varchar(20)
);
修改表:
格式:alter table 表名 ...
修改表名:
格式:
alter table 老表名 rename to 新表名;
例如:
alter table user1 rename to user10;
添加字段:
格式:
alter table 表名 add [column] 新的字段描述;
例如:
alter table user add password varchar(20);
修改字段类型:
格式:
alter table 表名 modify [column] 新字段描述;
例如:
alter table user modify password int;
修改字段名称:
格式:
alter table 表名 change [column] 旧字段名 新字段描述;
例如:
alter table user change password pwd varchar(20);
删除字段:
格式:
alter table 表名 drop [column] 字段名;
例如:
alter table user drop pwd;
删除表:
格式:
drop table 表名;
例如:
drop table user10;
常用命令:
进入或者切换数据库:use 数据库名称;
查看当前数据库下所有表:show tables;
查看表结构:desc 表名;
查看建表语句:show create table 表名;
/////////////////////////////////////
DML:数据库操作语言 ☆
操作对象:记录
关键词:insert update delete
插入记录:
格式1:
insert into 表名 values(值1[,值2...]);
例如:
insert into user values(1,'微哥');
insert into user values(1,'weige');
注意:
默认插入全部的字段
values里面的值要和建表语句的字段顺序和类型保持一致
int可以不使用引号
varchar必须使用引号
格式2:
insert into 表名(字段名1[,字段名2...]) values(值1[,值2...]);
例如:
insert into user(name,id) values ('威戈',2);
注意:
插入指定的字段
values里面的值要和前面的字段顺序和类型保持一致
更新记录:
格式:
update 表名 set 字段名称=值[,字段名称=值..] [where 条件];
例如:
update user set name='张三';-- 修改了所有
update user set name='李四' where id='2';-- 有条件的修改
update user set id=3,name='王五' where id=2;
删除记录:
格式:
delete from 表名 [where 条件];
例如:
delete from user; -- 清空表
delete from user where id=1;
扩展:
在开发中,添加一个字段用来标识该条记录是否被删除.例如 isdel
///////////////////////////////
DQL:数据库查询语言 ☆
关键词:select
查询语句:select * from 表名;
搭建环境
CREATE TABLE `products` (
`id` INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(40) ,
`price` DOUBLE ,
`category` VARCHAR(40) ,
`pnum` INT(11) ,
`description` VARCHAR(255)
);
插入值:
INSERT INTO `products` VALUES(NULL,'感悟',100,'励志',100,'一次心灵的鸡汤');
INSERT INTO `products` VALUES(NULL,'java与模式',67,'计算机',200,'让你的编程,从些不一样');
INSERT INTO `products` VALUES(NULL,'java并发编程实战',190,'计算机',49,'实战大于理论');
INSERT INTO `products` VALUES(NULL,'设计模式解析',88,'计算机',86,'头脑风暴');
INSERT INTO `products` VALUES(NULL,'搭地铁游上海',28,'生活百科',120,'一次不一样的旅行');
INSERT INTO `products` VALUES(NULL,'时空穿行',65,'科技',87,'这是一本好书');
INSERT INTO `products` VALUES(NULL,'中国国家地理',45,'生活百科',100,'了解你生活的国家');
INSERT INTO `products` VALUES(NULL,'欧洲', NULL,'生活',200,'你梦中向往的地方');
INSERT INTO `products` VALUES(NULL,'网管员必备宝典',35,'计算机',120,'上网新手必备书籍');
基本查询:
1.查询出所有商品信息
-- 查询全部
select * from products;
select id,name,price,pnum,category from products;
2.查询出所有商品的名称,价格,类别及数量信息
-- 查询部分字段
-- 格式 :select 字段名1[,字段名2...] from 表名;
select name,price,category,pnum from products;
3.查询出所有的商品类别
-- 去重操作
-- 格式 :select distinct 字段名1[,字段名2...] from 表名;
select category from products;
select distinct category from products;
4.查询出所有商品的名称及价格,将所有商品价格加10
-- 可以在查询的结果之上进行运算.
select name,price+10 from products;
-- 注意 :null和任意数据进行运算结果都是null
-- 可以通过 ifnull(字段名,默认值) 例如:ifnull(price,0) 若价格为null则按0处理
select name,ifnull(price,0)+10 from products;
5.查询出每一个商品的总价及名称
select name,pnum*price from products;
-- 字段起别名
-- 格式: 字段 [as] 别名
select name,pnum*price as 总价 from products;
select name,pnum*price `总 价` from products;
select name,pnum*price '总 价' from products;
/////////////////////////
条件查询
格式:
select * from 表名 where 条件;
select 字段1[,字段2...] from 表名 where 条件;
1.查询所有计算机类商品信息
-- 条件写法1: 支持关系运算符 > >= < <= = !=(<>)
-- 格式:字段名 运算符 值;
select * from products where category='计算机';
select * from products where category!='计算机';
select * from products where category<>'计算机';
2.查询出商品价格大于90的商品信息
select * from products where price > 90;
3.查询出商品总价大于10000的商品信息
select * from products where price*pnum > 10000;
4.查询出价格在100-200之间的商品信息
-- 条件写法2:支持逻辑操作符 and or not
-- 格式: 表达式1 and|or 表达式2
-- 格式: not 表达式
select * from products where price>=100 and price<=200;
-- 条件写法3:支持 between and 操作
-- 格式: 字段 between 较小值 and 较大值
select * from products where price between 100 and 200;
5.查询出商品价格是65,100或190的商品信息
-- 条件写法4 :支持in操作
-- 格式: 字段 in (值1[,值2...])
select * from products where price = 65 or price=100 or price=190;
select * from products where price in (65,100,190);
6.查询出商品的名称中包含java的商品信息。
-- 条件写法5:匹配操作 like
-- 格式 : 字段 like 匹配规则;
-- 匹配内容
like '龙' 值为龙
like '%龙' 值以龙结尾
like '龙%' 值以龙开头
like '%龙%' 值包含龙
-- 匹配个数
like '_' 值为一个字符
like '__' 值为两个字符
select * from products where name like '%java%';
select * from products where name like '%JAVA%';
7.查询出书名是两个字的商品信息
select * from products where name like '__';
-- length(字段名) = 值
select * from products where length(name)=6;
8.查询出商品价格不为null商品信息
错误的:select * from products where price != null;
-- 条件写法6: null操作
-- 格式1:字段 is null
select * from products where price is null;
-- 格式2:字段 is not null
select * from products where price is not null;
-- select * from products where not price is null;
排序:order by
格式1:
select * from 表名 [where 条件] order by 排序字段 排序方式;
格式2:
select * from 表名 [where 条件] order by 排序字段1 排序方式,排序字段2 排序方式;
排序方式:
升序:asc(默认)
降序:desc
1.查询出所有商品,并根据价格进行升序排序
select * from products order by price;
2.查询出所有商品,根据数量进行升序排列,如果数量相同,根据价格进行降序排列
select * from products order by pnum asc,price desc;
聚集函数:
它是对一列的值进行计算,然后返回一个单一的值;另外聚合函数会忽略空值
sum(字段):求和
count(字段):计数
max(字段):最大值
min(字段):最小值
avg(字段):平均数
格式:
select 聚集函数 from 表名 [where 条件];
1.统计商品表中共有多少条记录
select count(id) from products;
select count(price) from products;
开发中
select count(*) from products;
2.统计商品表中价格大于50的有多少条记录
select count(*) from products where price>50;
3.统计有多少商品
select sum(pnum) from products;
4.统计所有商品的总价值
select sum(pnum*price) from products;
5.统计所有商品的平均价格
select sum(pnum*price)/sum(pnum) from products;
-- round(值,保留几位小数)
select round(sum(pnum*price)/sum(pnum),2) '平均价格' from products;
6.统计出记录中pnum的平均值
select avg(pnum) from products;
7.统计出商品表中price最大值
select max(price) from products;
8.统计出商品表中price最小值
select min(price) from products;
9.统计出生活百科类图书的总数量
select sum(pnum) from products where category='生活百科';
分组:group by
格式1:
select 分组字段[,集合函数] from 表名 [where 条件] group by 分组字段;
格式2:
select 分组字段[,集合函数] from 表名 [where 条件] group by 分组字段 having 条件;
1.对商品分类别统计,求出每一种类商品的总数量
select category,sum(pnum) from products group by category;
2.对商品分类别统计,求出每一种类商品的总数量,数量要大于100
错误的:select category,sum(pnum) from products where sum(pnum)>100 group by category;
select category,sum(pnum) from products group by category having sum(pnum)>100;
where和having的区别:
1.where后面不能使用聚集函数,having可以
2.where是对分组之前的数据进行筛选,having是对分组之后的数据进行筛选.
DQL的使用小结:
格式:
select 分组字段[,聚集函数] from 表名 where 条件 group by 分组字段 having 条件 order by 排序字段 asc|desc;
注意:
order by 永远放在语句的最后.
执行顺序:
1.先确定那张表. from
2.确实是否有条件 where
3.若需要分组,使用group by
4.若需要对分组之后的数据进行筛选,执行having
5.确定要显示那些字段,执行select
6.确定字段的显示方法,执行order by
约束:
保证数据的有效性和完整性.
在mysql中有主键约束(primary key),唯一约束(unique),非空约束(not null),外键约束(foreign key)
主键约束(primary key)
作用:确定字段是该条记录唯一标识.
注意:
主键可以是一个字段,也可以是多个字段.
一张表只能有一个主键.
特点:
被主键约束修饰过的字段唯一 非空.
使用:
格式1:在声明字段的同时,添加主键约束
create table pk01(
id int primary key,
name varchar(20)
);
insert into pk01 values(1,'tom');-- 成功
insert into pk01 values(1,'tom');-- 错误 Duplicate entry '1' for key 'PRIMARY'
insert into pk01 values(null,'tom');-- 错误的 Column 'id' cannot be null
扩展:
一般情况下 使用id作为主键,id没有任何实际意义.
格式2:在声明字段之后,在约束区域添加主键约束 : [constraint] primary key(字段1[,字段2...])
create table pk02(
id int,
name varchar(20),
primary key (id,name)
);
insert into pk02 values(1,'tom');
insert into pk02 values(1,'jack');
insert into pk02 values(1,null);-- 错误
insert into pk02 values(null,'rose');
格式3:创建完表之后,通过修改表结构添加主键约束. alter table 表名 add primary key(字段1[,字段2...])
create table pk03(
id int,
name varchar(20)
);
alter table pk03 add primary key(name);
使用小结:
开发中最常使用的是第一种.只能在一个字段上添加主键约束.
若需要在多个字段上添加主键约束(联合主键),请使用第二种或第三种.
create table pk04(
id int primary key,
name varchar(20) primary key
);-- 错误的 Multiple primary key defined
/////////////////
唯一约束(unique)
特点:被修饰的字段唯一.对null值不起作用
格式1:在声明字段的同时,添加唯一约束 写法 : 字段名 字段类型 unique
create table un01(
id int unique,
name varchar(20)
);
insert into un01 values(1,'tom');-- 成功
insert into un01 values(1,'tom');-- 错误 Duplicate entry '1' for key 'id'
insert into un01 values(null,'tom');-- 成功
格式2:在声明字段之后,在约束区域添加唯一约束 写法:[constraint] unique(字段1[,字段2..])
create table un02(
id int,
name varchar(20),
unique(id,name)
);-- 添加联合的唯一约束
insert into un02 values(1,'tom');
insert into un02 values(1,'tom');-- Duplicate entry '1-tom' for key 'id'
insert into un02 values(1,'java');
create table un04(
id int unique,
name varchar(20) unique
);
格式3:在创建完表之后,通过修改表结构添加唯一约束 alter table 表名 add unique(字段1[,字段2])
create table un03(
id int,
name varchar(20)
);
alter table un03 add unique(id);
使用小结:
在开发中一般不添加.
在项目最后上线的时候通过第三种方式添加唯一约束.
///////////////////
非空约束(not null)
特点:被修饰的字段非空
格式:在声明字段的同时添加非空约束.
create table nn(
id int not null,
name varchar(20) not null
);
insert into nn values(null,'tom');-- 错误的
insert into nn values(1,null);-- 错误的
/////////
插入记录乱码问题:
方法1:临时修改
set names gbk;
方法2:永久修改
安装目录下/my.ini文件
大概50行左右
[client]
port=3306
[mysql]
default-character-set=utf8
把utf8改成gbk,然后重启服务
set names gbk 知识点补充(
到MySQL命令行输入“SET NAMES UTF8;”,然后执行“show variebles like“character_set_%”;”,发现原来为latin1的那些变量“character_set_client”、“character_set_connection”、“character_set_results”的值全部变为utf8了,原来是这3个变量在捣蛋。
查阅手册,上面那句等于:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
看看这3个变量的作用:
信息输入路径:client→connection→server;
信息输出路径:server→connection→results。
换句话说,每个路径要经过3次改变字符集编码。以出现乱码的输出为例,server里utf8的数据,传入connection转为latin1,传入results转为latin1,utf-8页面又把results转过来。如果两种字符集不兼容,比如latin1和utf8,转化过程就为不可逆的,破坏性的。
但这里要声明一点,“SET NAMES UTF8”作用只是临时的,MySQL重启后就恢复默认了。
)
///////////////////////////////////////
字段类型:
java mysql
byte tinyint
short smallint
int int☆
long bigint
char
String char(n) char(5):长度不可变 例如:存入abc 在数据库中"abc "
varchar(n)☆ varchar(5):长度可变 例如:存入abc 在数据库中"abc"
boolean
float float double(m,d) m代表的数字的长度,d代表小数位个数
double(5,2) 存放的最大值为 999.99
double double
java.sql.Date date:日期
java.sql.Time time:时间
java.sql.Timestamp timestamp时间戳
dateTime:日期和时间.
java.sql.Blob blob
java.sql.Clob text
三个小知识
auto_increment(开发)
作用:被他修饰过的字段可以自增.
格式:
字段名称 字段类型 primary key auto_increment
特点:
1.被修饰的字段类型可以自增,一般是int
2.被修饰的字段必须是一个key,一般是primary key
create table ai01(
id varchar(20) primary key auto_increment,
name varchar(20)
);-- 错误 Incorrect column specifier for column 'id'
create table ai02(
id int auto_increment,
name varchar(20)
);-- 错误 Incorrect table definition; there can be only one auto column and it must be defined as a key
create table ai(
id int primary key auto_increment,
name varchar(20)
);
使用的注意事项:
插入值的可以是指定的值.
插入值的时候把他指定为null.
插入值的时候忽略掉他也是可以的.
insert into ai values(12,'sansan');
insert into ai values(null,'xiaosan');
insert into ai(name) values('xiaosi');
///////////////////////
truncate:
作用:清空表.干掉表结构,创建一个新表.
格式:truncate [table] 表名;
delete from 和truncate区别:
1.truncate 属于DDL语句,delete 属于DML语句
2.truncate干掉表结构,创建一个新表..delete是逐条删除记录.
//////////////////
default
作用:添加默认值
格式:字段名称 字段类型 [约束] default 默认值
例如:
create table de(
id int primary key auto_increment,
name varchar(20) default '张三丰'
);
insert into de values(null,'sansan');
insert into de values(null,null);
insert into de(id) values(null);
结论:不明确给定值的时候采用默认值.
/////////////////////////////////////
数据库的备份与还原
备份:
格式:在cmd窗口下输入
mysqldump -uroot -p密码 要备份的数据库>文件磁盘路径
例如:
mysqldump -uroot -p1234 day06>f:/day06_bak.sql
//////////////////
还原:
前提,必须手动创建目的地数据库
格式1:cmd窗口中输入
mysql -uroot -p密码 目的地数据库<文件磁盘路径
例如:
mysql -uroot -p1234 day0601<f:/day06_bak.sql
格式2:必须在目的地数据库中执行命令
source 文件磁盘路径
例如:
source f:/day06_bak.sql
常用的命令:
select database(); -- 查看当前所在的数据库
小工具(可视化)
多表的设计与实现☆
关系型数据库:存放实体与实体之间的关系.
用户<拥有> 订单<包含> 商品
一对多
设计:
在实际开发中,我们称一方(用户表)为一表或者主表,称多方(orders表)为多表或者从表
然后在多表的一方添加一个字段,字段名称自定义(一般使用主表的名称_id),字段的类型一般和主表的id保持一致.该字段我们称之为
外键.
实现:
user(用户表)
create table user(
id int primary key auto_increment,
username varchar(20)
);
orders(订单表)
create table orders(
id int primary key auto_increment,
price double,
user_id int
);
insert into user values(null,'强哥');
insert into user values(null,'聪哥');
insert into orders values(null,1314,1);
insert into orders values(null,1314,2);
insert into orders values(null,305,2);
为了保证数据的有效性和完整性,必须给表添加外键约束.
在多表的一方添加外键约束
格式:通过修改表结构,添加外键约束.
alter table 表名 add [constraint [外键名称]] foreign key(多表的外键) references 主表(主键);
例如:
alter table orders add foreign key (user_id) references user(id);
注意:
主表中不能删除从表中已引用的数据
从表中不能添加主表中不存在的数据
/////////////////////////////
多对多:
设计:
在开发中,一般会引入一个中间表,中间表中的字段一般为两表的主键,
通过中间表,就可以把多对多的关系拆分成两个一对多的关系.
一般我们会把中间表的两个字段设置成联合主键.
实现:
-- products(商品表)
create table products(
id int primary key auto_increment,
price double
);
-- orders_pro(中间表)
create table orders_pro(
oid int,
pid int,
primary key(oid,pid)
);
insert into products values(null,999);
insert into products values(null,305);
insert into products values(null,10);
insert into orders_pro values(1,1);
insert into orders_pro values(1,2);
insert into orders_pro values(1,3);
insert into orders_pro values(2,1);
insert into orders_pro values(2,2);
insert into orders_pro values(2,3);
insert into orders_pro values(3,2);
为了保证数据的完整性,添加外键约束.(中间表)
在中间表上添加两个外键约束
格式:
alter table 表名 add [constraint [外键名称]] foreign key (多表的外键) references 主表(主表的id);
例如:
alter table orders_pro add foreign key (oid) references orders(id);
alter table orders_pro add foreign key (pid) references products(id);
注意:
主表中不能删除从表中已引用的数据
从表中不能添加主表中不存在的数据
////////////////////////
一对一:
设计:
1.若一张表中的字段很少,二表合二为一
2.根据需求,一般在不常用的表上添加外键约束,实际上是把主键设置成外键即可
实现:
-- 人员person
create table person(
id int primary key auto_increment,
username varchar(20)
);
-- 身份证表 idcard
create table idcard(
id int primary key auto_increment,
idno varchar(25)
);
设置外键
alter table idcard add foreign key(id) references person(id);
////////////////////////////////////////////////////
多表的查询☆
环境搭建:
-- 用户表(user)
create table `user` (
`id` int auto_increment primary key,
`username` varchar(50) -- 用户姓名
);
-- 订单表(orders)
create table `orders` (
`id` int auto_increment primary key,
`price` double,
`user_id` int
);
-- 给订单表添加外键约束
alter table orders add constraint user_fk foreign key (user_id) references user(id);
-- 向user表中添加数据
insert into user values(1,'张三');
insert into user values(2,'李四');
insert into user values(3,'王五');
insert into user values(4,'赵六');
-- 向orders 表中插入数据
insert into orders values(1,1314,1);
insert into orders values(2,1314,1);
insert into orders values(3,15,2);
insert into orders values(4,315,4);
insert into orders values(5,1014,null);
1.查询用户的订单,没有订单的用户不显示
2.查询所有用户的订单详情
3.查询所有订单的用户详情
笛卡尔积:(了解)
格式:
select a.*,b.* from a,b
隐式内连接:
格式:
select a.*,b.* from a,b where 连接条件;
例如:查询用户的订单,没有订单的用户不显示
select user.*,orders.* from user,orders where user.id=orders.user_id;
内连接:
格式:
select a.*,b.* from a [inner] join b on 链接条件;
注意:
内连接的查询结果和隐式内连接的查询结果一样.
例如:
select user.*,orders.* from user join orders on user.id=orders.user_id;
左外连接:
格式:
select a.*,b.* from a left [outer] join b on 链接条件;
意思:
以left左边的表为主,显示它的所有记录,根据链接条件查询b表,若符合条件则显示该条记录,否则以null值显示.
例如:查询所有用户的订单详情
select user.*,orders.* from user left join orders on user.id=orders.user_id;
右外连接:
格式:
select a.*,b.* from a right [outer] join b on 连接条件;
注意:
左外连接和右外连接可以等价
意思:
以right右边的表为主,显示它的所有记录,根据链接条件查询a表,若符合条件则显示该条记录,否则以null值显示.
例如:查询所有订单的用户详情
select user.*,orders.* from user right join orders on user.id=orders.user_id;
select orders.id,orders.price ,user.* from orders left join user on user.id=orders.user_id;
子查询:
一个查询的条件是另一个查询的结果.
1.查看用户为张三的订单详情
select id from user where username='张三';-- id=1
select * from orders where user_id=1;
合二为一
select * from orders where user_id=(select id from user where username='张三');
2.查询出订单的价格大于300的所有用户信息。
select user_id from orders where price>300;-- 1,1,4,null
select * from user where id in(1,1,4,null);
合二为一:
select * from user where id in(select user_id from orders where price>300);
3.查询订单价格大于300的订单信息及相关用户的信息。
方式1:select user.*,orders.* from user,orders where user.id=orders.user_id and orders.price>300;
方式2:
首先 查询订单价格大于300的订单信息
select * from orders where price>300;
然后,通过上一条语句结果和user进行关联查询即可
select u.* ,b.* from user u,(select * from orders where price>300) b where u.id=b.user_id;
给表起别名,在from 之后 :表 [as] 别名
还没有评论,来说两句吧...