mysql选择题解析_mysql一道题的解析

某消费系统中包含2张表,用户信息表和消费流水表,结构和数据如下:

用户表:user

ID

(自增主键)

NAME

(非空)

Balance

(非空)

1

A

19.50

2

A

20.50

3

B

100.00

4

C

200.00

流水表:charge

ID

(自增主键)

User_id

(非空)

FEE

(非空)

Update_date

1

1

11.00

2013-10-01

2

2

21.00

2013-10-05

3

3

31.00

2013-10-06

1)请按要求写出上面两张表的建表sql语句;

2)请分别写出下面两组sql语句的输出结果;

Delete from user;

Insert into user value (‘’, ‘D’, 300);

Truncate user;

Insert into user value (‘’, ‘D’, 300);

3)请写出能产生下面查询结果的SQL语句:

Name

Count

Balance

FEE

A

2

40.00

32.00

B

1

100.00

31.00

C

1

200.00

0.00

4)系统运行一段时间后,流水表的记录变得非常大,通过用户名(NAME)查询用户消费记录(FEE)时响应速度非常慢,请简述你的优化方案。

先建个库

CREATE DATABASE

IF NOT EXISTS mybase

DEFAULT CHARACTER SET utf8

COLLATE utf8_general_ci;

MySQL这样选择数据库字符集和数据库校对规则:

·如果指定了CHARACTER SET X和COLLATE Y,那么采用字符集X和校对规则Y。

·如果指定了CHARACTER SET X而没有指定COLLATE Y,那么采用CHARACTER SET X和CHARACTER SET X的默认校对规则。

·否则,采用服务器字符集和服务器校对规则。

如果在CREATE TABLE语句中没有指定表字符集和校对规则,则使用数据库字符集和校对规则作为默认值。

(1)

CREATE TABLE `user` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT, //对主键自动编号

`name` varchar(255) NOT NULL,

`balance` decimal(10,2) NOT NULL, //采用小数,保留两位。

PRIMARY KEY (`id`),设置主键,前面进行了自动编号的设置

KEY (`name`)

) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

注:此时如果我们添加数据的时候添加错了,然后我们用 delect from user where id=“?” 删除后,再添加新的数据主键自增字段不会重置 如下图:

de772a0a00f80a06e079b1690ffc1910.png

此时我们应该使用

mysql> truncate table uses; //清空操作

接下来重新插入数据即可

INSERT INTO `user` (`name`, `balance`) VALUES ('A', 19.50);INSERT INTO `user` (`name`, `balance`) VALUES ('A', 20.50);INSERT INTO `user` (`name`, `balance`) VALUES ('B', 100.00);INSERT INTO `user` (`name`, `balance`) VALUES ('C', 200.00);

CREATE TABLE `charge` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `user_id` int(10) unsigned NOT NULL, `fee` decimal(10,2) NOT NULL, `update_date` char(10) NOT NULL, //unsigned :非负数

PRIMARY KEY (`id`),

KEY (`user_id`)

) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

INSERT INTO `charge` (`user_id`, `fee`, `update_date`) VALUES (1, '11.00', '2013-10-01');

INSERT INTO `charge` (`user_id`, `fee`, `update_date`) VALUES (2, '21.00', '2013-10-05');

INSERT INTO `charge` (`user_id`, `fee`, `update_date`) VALUES (3, '31.00', '2013-10-06');

输出结果

mysql> select * from user;

+----+------+---------+

| id | name | balance |

+----+------+---------+

|  5 | D    |  300.00 |

+----+------+---------+

1 row in set (0.00 sec)

正如上面提到了新的数据主键自增字段不会重置

使用Truncate user;

再插入结果如下

mysql> select * from user;

+----+------+---------+

| id | name | balance |

+----+------+---------+

|  1 | D    |  300.00 |

+----+------+---------+

1 row in set (0.00 sec)

3)

SELECT `name` as `Name`,

COUNT(`name`) as `Count`,

SUM(`balance`) as `Balance`,

IFNULL(SUM(`fee`), 0.00) as `Fee` FROM `user`

LEFT JOIN `charge` on `user`.`id` = `charge`.`user_id` //LEFT JOIN 左连接 以user表为基础匹配和 charge比较,找出符合 id的值等于user id的记录(条件)。

GROUP BY `name` //把满足上述过程的记录弄到一个分组里

ORDER BY `Count` DESC;  //     ORDER BY对结果集进行排序  asc 按升序排列 desc 按降序排列

IFNULL(SUM(`fee`), 0.00)表示如果为NULL,则设为0.00.

COALESCE(SUM(`fee`), 0.00)表示合并SUM(`fee`)和0.00.

查询结果:

A  2  40.00   2.00

B  1  100.00  31.00

C  1  200.00  0.00

SELECT `name`,

COUNT(`name`),

SUM(`balance`),

SUM(`fee`) FROM `user`

INNER JOIN `charge` on `user`.`id` = `charge`.`user_id`

WHERE `name` = 'A';

(4)

给user表的字段name和charge表的user_id建立索引.

如果需要外键约束user_id:

CREATE TABLE `charge_fk` (

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

`user_id` int(10) unsigned NOT NULL,

`fee` decimal(10,2) NOT NULL,

`update_date` char(10) NOT NULL,

PRIMARY KEY (`id`),

KEY (`user_id`),

CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;

INSERT INTO `charge_fk` (`user_id`, `fee`, `update_date`) VALUES (1, '11.00', '2013-10-01');

INSERT INTO `charge_fk` (`user_id`, `fee`, `update_date`) VALUES (2, '21.00', '2013-10-05');

INSERT INTO `charge_fk` (`user_id`, `fee`, `update_date`) VALUES (3, '31.00', '2013-10-06');

感谢热心的解答者                                  原答案作者:@eechen 感谢开源力量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值