面试题答案
一键面试表结构设计
- 合理划分表:
- 将不同主题的数据分开存储在不同的表中。例如,用户相关信息放在
users
表,应用使用记录放在usage_records
表等,避免一个表过于庞大和复杂。 - 遵循范式原则,减少数据冗余,但也要考虑查询效率,对于一些经常联合查询的表,可以适当增加冗余字段。比如在订单表
orders
中,除了存储用户ID外,为了快速获取用户姓名,可冗余存储用户姓名user_name
字段(前提是用户姓名修改频率较低)。
- 将不同主题的数据分开存储在不同的表中。例如,用户相关信息放在
- 字段类型选择:
- 使用最小的数据类型来存储数据,以减少存储空间。例如,对于状态字段(如是否激活),使用
BOOL
类型(在SQLite中可以用INTEGER
0或1表示)而不是TEXT
。 - 对于日期和时间,优先使用
INTEGER
存储时间戳,这样占用空间小且便于比较和计算。
- 使用最小的数据类型来存储数据,以减少存储空间。例如,对于状态字段(如是否激活),使用
索引策略
- 主键索引:
- 每个表都应该有一个主键,主键会自动创建索引,确保表中每行数据的唯一性。例如,在
users
表中,user_id
作为主键,可快速定位特定用户记录。
- 每个表都应该有一个主键,主键会自动创建索引,确保表中每行数据的唯一性。例如,在
- 普通索引:
- 对经常用于查询条件、排序、连接操作的字段创建索引。比如在
usage_records
表中,如果经常根据usage_date
字段查询特定日期的使用记录,就对usage_date
字段创建索引。 - 避免创建过多索引,因为索引会增加写操作的开销,每个索引都需要额外的存储空间,并且插入、更新、删除操作时都需要更新索引。
- 对经常用于查询条件、排序、连接操作的字段创建索引。比如在
- 复合索引:
- 当多个字段经常一起作为查询条件时,创建复合索引。例如,在
orders
表中,如果经常根据user_id
和order_date
联合查询订单,可创建复合索引(user_id, order_date)
。注意复合索引中字段的顺序,最常使用的字段应放在前面。
- 当多个字段经常一起作为查询条件时,创建复合索引。例如,在
数据分区
- 范围分区:
- 根据某个字段的范围进行分区,例如按照时间范围。在
usage_records
表中,可按月份将数据分区,每个月的数据存储在不同的分区(在SQLite中可通过创建不同的表来模拟分区)。如usage_records_202301
表存储2023年1月的使用记录,usage_records_202302
表存储2023年2月的使用记录等。这样在查询特定时间段的数据时,可直接定位到相应的分区表,减少查询的数据量。
- 根据某个字段的范围进行分区,例如按照时间范围。在
- 哈希分区:
- 如果数据分布比较均匀,可考虑哈希分区。例如,对
users
表根据user_id
进行哈希分区,将数据均匀分配到多个分区(表)中,以分散数据负载,提高读写性能。例如使用哈希函数将user_id
映射到不同的表,如users_0
、users_1
等。
- 如果数据分布比较均匀,可考虑哈希分区。例如,对
其他优化
- 定期清理:
- 对于一些过期或不再需要的数据,定期进行清理,以减少数据库的大小,提高查询性能。例如,删除超过一定时间的历史使用记录。
- 缓存机制:
- 在应用层面设置缓存,对于经常查询且不经常变化的数据,缓存到内存中,减少对数据库的查询次数。例如,对于一些配置信息、热门用户数据等进行缓存。