骑着猪找未来
问题一:从文中的信息来看,count(n)或count(*)是走索引的,猜测sum()是因为不走索引导致的
问题二:书写顺序为select、from、where、group by、 order by、having
讲师回答 / 勤一
骑猪你好,确实是这样的,顺序是对的
阿斯拉菲
问题1 case when 经常统计、纵表转横表的时候用过,ifnull, if 个人相对用的少
问题2 这个亲身体会,mysql 5.x版本默认大小写不敏感,mysql 8 默认大小写敏感,修改的话必须是数据库初始化之前修改,之后更改是无效的
讲师回答 / 勤一
是的,这些判断语句在部分情况下是比较好用的,但是,如果不这样写,其实在代码中判断,效率也是非常高的,不一定非要这样用。关于大小写敏感的问题,我的个人习惯是精确查找,而不是依赖于数据库系统的特性。
沁尘
问:将时间转换为时间戳,并使用 int 或者 bigint 类型去存储,你觉得这样可行吗 ?
答:看正文的时候正好奇为啥没提到存储int/bigint时间戳,用int/bigint和datetime存储在不同项目都使用过,感受就是int/bigint计算上很方便。特别是当前端项目对于时间展示有不同的格式需求的时候,数据库中存储的是int/bigint(或者vo层转换)直接返回给前端,前端可以更方便的定制格式而不用先把datetime转成时间戳。但是如果没这方面的需求,那直接存储datetime就是最方便的,可以减少转换的次数。所以个人觉得,从存储角度上来说,如果没有格式定制的需求,直接存储datetime最省事。
问:大多数时候,我们会选择将主键设置为 bigint 数据类型,你知道这是为什么吗 ?
答:不知道
讲师回答 / 勤一
沁尘你好:
第一个问题,是否可以考虑将时间存储为整型?这是完全可以的,正如你所说,时间是整型的话,前端可以方便的进行转换,而且不用考虑精度的问题,且这种转换带来的性能损耗几乎是可以忽略不计的。当然,如果仅仅是 java 系统之间使用的话,使用 datetime 存储是最方便的,序列化和反序列化都只需要一个注解就可以完成。
第二个问题,为什么考虑将主键设置为 binint 类型?这里的主要思想就是为了将来的扩展,因为 int 类型的最大表示范围大约是 20 亿,这对于 99% 的项目都基本足够用了。但是,如果考虑到将来业务发展的比较迅速,就需要使用 bigint 了。如果一开始没有使用 bigint,而是使用 int,那么,后期的迁移将会是很大的工作量。
街边七号
1.为什么执行flush logs?猜测可能mysql执行操作后不会立即将操作信息记录在binlog,而是停留在内存中由mysql服务器在合适的时机进行异步刷盘,执行flush logs来确保最新的数据库操作可能记录在binlog中,来防止数据恢复都是
2.不知道
讲师回答 / 勤一
第一个问题说的是对的,先保存在内存中,起到缓冲的作用;第二个问题的话,其实就是指定起始位置和起始时间
沁尘
问:如果你的表没有定义主键,你知道 MySQL 会怎么做吗 ?
答:Innodb表中在没有默认主键的情况下会生成一个6byte空间的自动增长主键
我需要创建一个学校库,存储教师、学生、院系等信息,你觉得叫做 school 好吗 ?为什么 ?
答:个人觉得业务初期可能没问题。但是学生表后期会膨胀,很有可能独立成一个库或者为这个表做备份库,如果这个学校库起名叫school,那学生库或者学生表的备份库起名字的时候选择会比较苦难,不大好起一个简要达意的名字,不知道这么考虑对不对。
问:我编写的 SQL 语句需要做多表的 join 操作,应该给哪些列建索引呢 ?
答:where子句中的字段
讲师回答 / 勤一
沁尘你好:第一个问题,如果你的表没有定义主键,那么 MySQL 首先判断表中是否有非空的唯一索引,如果有,则该列即为主键;如果不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针。第二个问题,直接命名为 school 并不好,最好是加上一些前缀(比如地域之类的),主要目的是方便未来的扩展,比如加入其它的 school,不会同名。第三个问题,join 操作的话,where 条件和 join 的列最好都加上索引,但是,此时需要考虑索引的个数不要过多(一般一张表的索引个数不超过5个)。
街边七号
1. 用mybatis动态sql作批量录入
2. 可以考虑, 但此时sql耗时应基本集中在数据录入和更新索引的操作上, 性能受限于磁盘的因素应该比较大, 上多线程不如换ssd.
3. 单条录入需要mysql服务器每次都检查语法编译sql语句耗时较长, 批量和Load data可以省去很多这些事件, 但同样的批量录入这种形式增大了单条sql的大小及设置的package参数。此时单条sql从客户端发送到mysql服务器的时候会比较长,占用带宽。
街边七号
1. a.自增主键. b.尽量保证字段小一些. c.适当的冗余存储. d. 尽量让列值非空.
2. where子句字段类型和操作值的类型不一致如varchar类型的列`year`判断时使用where year = '2020'; like模糊前缀匹配; 对于聚簇索引条件丢失前缀匹配; where中使用SQL函数; 查询不使用索引列.
3.
街边七号
1. 环形哈希空间,添加节点后很多数据不需要移动。
2. 垂直拆分实现简单,而且水平拆分可能会导致where查询实现困难。
3. id决定了数据记录存放的库和表,可以定位到数据的存放位置。
4. 使用定时任务做同步,但是业务中直接查询结果由于定时任务可能延时可能变得不可信,需要自行校验
5.没想到什么好办法,就是自己维护一个userid和这些信息数据映射关系,并以此来找到userId再进行查询
无心铁憨憨
一哥,有个问题没想明白,在事物隔离级别为可重复读的情况下,事物A第一次读取的数据为1800,然后事物B修改为2000,事物A再次读取还是1800,因为事物B没有进行提交,但是当事物B提交之后再读取还是1800,那2000去哪里了,是否要等事物A执行完毕之后,再次查询,才会读到最新的2000?还是说需要在一个新的会话中才能读取到最新的数据?
讲师回答 / 沁尘
不管事务B提交了没有,事务A读到的都是这条记录的快照(1800时的状态),2000在事务B提交后就写到新的快照副本去了,这时候另一个事务如果查询,那就是看到2000这个状态的快照副本了。
想好名字再改
老师,假设我要查询每个用户能够接受的最大的预算的广告信息该怎么写
我目前的写法
SELECT user_id,MAX(budget) FROM ad_unit WHERE unit_status = 0 GROUP BY user_id
我还想看到这条广告的详细信息
讲师回答 / 勤一
最好的做法不是写一条 SQL 语句,而是在代码中经过两次查询,再去拼接对应的信息