如何在 SQL 数据库中存储商店营业时间?
How to store a store opening hours in an SQL database?
我正在为商店(实际上是餐馆)开发应用程序,需要为其设计 PostgreSQL 数据结构。
例如,餐厅的营业时间可能为周一至周五 7:30 至 17:00 以及第二天 20:30 至 1:00。
每个工作日要存储的数据类似于 ['Monday', true, 450, 1050, 1230, 1500 ]
,为真 ===“它在星期一开放”,450,开放时间是午夜过后 450 分钟(参见 here), i.e. at 7:30h, closes at 17:30h, reopens at 20:30h, and closes at 1 a.m. (split hours and close time after midnight are not at all unusual in my home country, Spain). Of course, I could dispense with the first two elements, 'Monday' and 'true', but they will probably make front-end development easier (e.g. see model for data input).
我已经确定了至少四个在 PostgreSQL 数据库中存储数据的可行选项:
1) 'restaurants' table 中的列 'opening_hours' 具有 jsonb 数据类型
[
['Monday', 真, 450, 1050, 1230, 1500 ]
...
['Sunday', 错误, 0, 0, 0, 0 ]
]
2) table 'restaurants'
中每小时一栏
我可能会省略上面显示的前两个元素('Monday' 和 'true')。这会将 7 x 4 = 28 列添加到我的 table:
- openMon1
- closeMon1
- openMon2
- closeMon2
- openTue1
- ...
3) 新 table 'opening_hours'
使用外键 'restaurant_id' 引用 table 'restaurants' 中的 'id',设计与 2) 相同。
4) 所有 7 个工作日的数据类别列
例如,列 'open1' 的格式为“0450-0450-0450-0450-0450-0000-0000”,如 here。因此,我会像选项 1) 那样汇总数据,但我看不出后者比前一个选项有任何真正的优势。
目前,选项 1 足以满足我要实现的业务逻辑:以与 Google 类似的方式显示营业时间,因此我看不出有任何理由可以继续使用2) or 3) over 1), 当然我可能会错过未来发展的可能性。
什么数据结构遵循最佳实践?还有比这些更好的选择吗?
一种非常灵活且标准化良好的方法是将每个开盘时段存储为 table 中的一行。开放期可以编码为它开始的工作日、它开始的一天中的时间和它持续的持续时间。每个营业时间都通过外键链接到一家餐厅。
CREATE TABLE opening_period
(restaurant integer,
weekday integer,
time time,
duration interval,
PRIMARY KEY (restaurant,
weekday,
time,
duration),
FOREIGN KEY (restaurant)
REFERENCES restaurant
(id)
ON DELETE CASCADE,
CHECK (weekday >= 0
AND weekday < 7),
-- prevent overlapping opening periods
EXCLUDE USING gist (restaurant WITH =,
tsrange('epoch'::timestamp + time + weekday * INTERVAL '1 days',
'epoch'::timestamp + time + weekday * INTERVAL '1 days' + duration,
'[)') WITH &&));
我正在为商店(实际上是餐馆)开发应用程序,需要为其设计 PostgreSQL 数据结构。
例如,餐厅的营业时间可能为周一至周五 7:30 至 17:00 以及第二天 20:30 至 1:00。
每个工作日要存储的数据类似于 ['Monday', true, 450, 1050, 1230, 1500 ]
,为真 ===“它在星期一开放”,450,开放时间是午夜过后 450 分钟(参见 here), i.e. at 7:30h, closes at 17:30h, reopens at 20:30h, and closes at 1 a.m. (split hours and close time after midnight are not at all unusual in my home country, Spain). Of course, I could dispense with the first two elements, 'Monday' and 'true', but they will probably make front-end development easier (e.g. see model for data input).
我已经确定了至少四个在 PostgreSQL 数据库中存储数据的可行选项:
1) 'restaurants' table 中的列 'opening_hours' 具有 jsonb 数据类型
[
['Monday', 真, 450, 1050, 1230, 1500 ]
...
['Sunday', 错误, 0, 0, 0, 0 ]
]
2) table 'restaurants'
中每小时一栏我可能会省略上面显示的前两个元素('Monday' 和 'true')。这会将 7 x 4 = 28 列添加到我的 table:
- openMon1
- closeMon1
- openMon2
- closeMon2
- openTue1
- ...
3) 新 table 'opening_hours'
使用外键 'restaurant_id' 引用 table 'restaurants' 中的 'id',设计与 2) 相同。
4) 所有 7 个工作日的数据类别列
例如,列 'open1' 的格式为“0450-0450-0450-0450-0450-0000-0000”,如 here。因此,我会像选项 1) 那样汇总数据,但我看不出后者比前一个选项有任何真正的优势。
目前,选项 1 足以满足我要实现的业务逻辑:以与 Google 类似的方式显示营业时间,因此我看不出有任何理由可以继续使用2) or 3) over 1), 当然我可能会错过未来发展的可能性。
什么数据结构遵循最佳实践?还有比这些更好的选择吗?
一种非常灵活且标准化良好的方法是将每个开盘时段存储为 table 中的一行。开放期可以编码为它开始的工作日、它开始的一天中的时间和它持续的持续时间。每个营业时间都通过外键链接到一家餐厅。
CREATE TABLE opening_period
(restaurant integer,
weekday integer,
time time,
duration interval,
PRIMARY KEY (restaurant,
weekday,
time,
duration),
FOREIGN KEY (restaurant)
REFERENCES restaurant
(id)
ON DELETE CASCADE,
CHECK (weekday >= 0
AND weekday < 7),
-- prevent overlapping opening periods
EXCLUDE USING gist (restaurant WITH =,
tsrange('epoch'::timestamp + time + weekday * INTERVAL '1 days',
'epoch'::timestamp + time + weekday * INTERVAL '1 days' + duration,
'[)') WITH &&));