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=“?” 删除后,再添加新的数据主键自增字段不会重置 如下图:

mysql一道题的解析

此时我们应该使用

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 感谢开源力量

你可能感兴趣的:(mysql一道题的解析)