6. 将日期时间存储为各种日期时间类型
  不要使用Unix的时间戳或者字符串来存储日期,而是要将它们转换为各种日期时间类型。虽然SQL的日期计算函数并不是棒的,但是调用这些函数来处理时间戳总比自己来处理要简单。在查询时,我们需要为每一个涉及到从timestamp到datetime类型的转换的查询调用SQL的日期函数
  select date(from_unixtime(created_at)) from packages
  -- vs
  select date(created_at) from packages
  不要将年、月、日分别存储到不同的列中。因为这样会导致每个有关时间序列的查询都更加难写,而且也会在使用这张表的日期信息时给大多数的SQL初学者造成障碍。
  select date(created_year || '-' || created_month || '-' || created_day)
  -- vs
  select date(created_at)
  7. 总是使用UTC
  使用时区而不是UTC将导致无穷无尽的问题。好的工具(包括我们的Periscope)拥有你所需要的从UTC转换为你所在时区数据的所有功能。在Periscope中,简单地加个:pst可以将UTC转换为太平洋时间。
  select [created_at:pst], email_addressfrom users
  应该将数据库的时区设为UTC,并且所有datetime的列都应该是剥离时区后的类型(如,无时区的timestamp)。
  如果你的数据库的时区不是UTC,或者你的数据库混合了UTC和非UTC时间日期,那么时间序列的分析查询将会变得更加困难。
  8.单一的真相源
  一块数据应该只有单一的真相源(Source of Truth)。视图和汇总(Rollup)本身应该有所标示。这样做的话,数据的消费者会知道他们使用的数据和原生真相之间的区别。
  select *from daily_usage_rollup
  另一方面,将诸如user_id、user_id_old或者user_id_v2的遗留列都保留的话,只会带来无尽的困扰。因此请确保在日常维护中会进行删除废弃的表格和不再使用的字段的工作。
  9.优先使用没有JSON列的表格
  请不要使用列过多的表。如果一张表有超过几十个列并且其中一些是以序列命名(例如,answer1、answer2、answer3)的话,那么马上你会感到不好过了。
  正确的做法是将这样的表转化为不包含重复列的模式,因为这样的模式将很容易查询。例如,在一个查询中计算某个调查表中已完成的题目的数目:
  select
  sum(
  (case when answer1 is not null
  then 1 else 0 end) +
  (case when answer2 is not null
  then 1 else 0 end) +
  (case when answer3 is not null
  then 1 else 0 end)
  ) as num_answers
  from surveys
  where id = 123
  -- vs
  select count(response)
  from answers
  where survey_id = 123
  对于查询分析而言,从JSON列抽出数据的操作将大幅降低查询的性能。虽然有很多很棒的理由支持我们在产品中使用JSON列,但是对于查询分析来说并不是这样。大胆得将JSON列拆解为更简单数据类型,可以使查询分析变得更快更容易。
  10、不要过度规范化
  日期,邮编和不需要使用带有外键查询的表单独存放。过度地规范化将会导致每个查询后面都要带上一些相同的表连接操作。这样不但创建了许多重复的SQL,而且数据库为此还要做很多额外的工作。
  select
  dates.d,
  count(1)
  from users
  join dates on users.created_date_id = dates.id
  group by 1
  -- vs
  select
  date(created_at),
  count(1)
  from users
  group by 1
  表是数据库中的一等对象,拥有很多属于自己的数据。其余的任何数据都可以作为另一个更重要对象的附加列。
  更好的模式在等着你! 如你所期待的,对于你和团队的新成员来说,遵循这些规则将有助于下一张表或者数据仓库变得更容易查询。如果你不认可或者有更多的规则建议,请联系我们吧hello@periscope.io。我们很期待听到你的声音!