Creating custom event schedules. Should I use "LIKE"?

时间:2015-06-25 19:02:05

标签: sql database postgresql database-design

I'm creating a campaign event scheduler that allows for frequencies such as "Every Monday", "May 6th through 10th", "Every day except Sunday", etc. I've come up with a solution that I believe will work fine (not yet implemented), however, it uses "LIKE" in the queries, which I've never been too fond of. If anyone else has a suggestion that can achieve the same result with a cleaner method, please suggest it! +----------------------+ | Campaign Table | +----------------------+ | id:int | | event_id:foreign_key | | start_at:datetime | | end_at:datetime | +----------------------+ +-----------------------------+ | Event Table | +-----------------------------+ | id:int | | valid_days_of_week:string | < * = ALL. 345 = Tue, Wed, Thur. etc. | valid_weeks_of_month:string | < * = ALL. 25 = 2nd and 5th weeks of a month. | valid_day_numbers:string | < * = ALL. L = last. 2,7,17,29 = 2nd day, 7th, 17th, 29th,. etc. +-----------------------------+ A sample event schedule would look like this: valid_days_of_week = '1357' (Sun, Tue, Thu, Sat) valid_weeks_of_month = '*' (All weeks) valid_day_numbers = ',1,2,5,6,8,9,25,30,' Using today's date (6/25/15) as an example, we have the following information to query with: Day of week: 5 (Thursday) Week of month: 4 (4th week in June) Day number: 25 Therefore, to fetch all of the events for today, the query would look something like this: SELECT c.* FROM campaigns AS c, LEFT JOIN events AS e ON c.event_id = e.id WHERE ( e.valid_days_of_week = '*' OR e.valid_days_of_week LIKE '%5%' ) AND ( e.valid_weeks_of_month = '*' OR e.valid_weeks_of_month LIKE '%4%' ) AND ( e.valid_day_numbers = '*' OR e.valid_day_numbers LIKE '%,25,%' ) That (untested) query would ideally return the example event above. The "LIKE" queries are what have me worried. I want these queries to be fast. By the way, I'm using PostgreSQL Looking forward to excellent replies!

1 个答案:

答案 0 :(得分:1)

使用数组:

CREATE TABLE events (id INT NOT NULL, dow INT[], wom INT[], dn INT[]);

CREATE INDEX ix_events_dow ON events USING GIST(dow);
CREATE INDEX ix_events_wom ON events USING GIST(wom);
CREATE INDEX ix_events_dn ON events USING GIST(dn);

INSERT
INTO    events
VALUES  (1, '{1,3,5,7}', '{0}', '{1,2,5,6,8,9,25,30}'); -- 0 means any

,然后查询:

SELECT  *
FROM    events
WHERE   dow && '{0, 5}'::INT[]
        AND wom && '{0, 4}'::INT[]
        AND dn && '{0, 26}'::INT[]

这将允许使用索引过滤数据。