Takvim/Yinelenen Yinelenen Olaylar - En İyi Saklama Yöntemi
Özel olaylar bir sistem inşa ediyorum, ve eğer yinelenen bir olay varsa bu gibi görünüyor:
Olay her 4 gün, 3 Mart 2011 tarihinde başlayan tekrarlar
ya
B olayı her hafta 2 Mart Salı günü 1, 2011'den itibaren tekrar eder
Nasıl basit arama yapmak için, bir şekilde bir Veritabanında depolar. Eğer olaylar çok sayıda varsa performans sorunları istemiyorum, ve takvim işlerken her biri üzerinden gitmek zorundayım.
CEVAP
Saklama"," Yinelenen Desen . Basit
MySQL tabanlı PHP/takvimimi için, yinelenen/tekrarlanan olay bilgi etkili, muhtemelen saklamak istedim. Çok sayıda satır yapmak istemedim, ve kolayca belirli bir tarihte gerçekleşecek tüm olaylar arama yapmak istedim.
Düzenli aralıklarla oluşan yinelenen bilgileri saklamak en büyük aşağıdadır yöntemi, her gün, her gibingün, her hafta, her ay, her yıl, vs vs. Bu ayrı ayrı her hafta Salı günü başlangıç olarak saklanan ve bir Perşembe gününden itibaren her hafta oldukları için her Salı ve Perşembe tür desenler içerir.
İki tablo var varsayarak, bu events
adı:
ID NAME
1 Sample Event
2 Another Event
Ve bunun gibi bir tablo events_meta
olarak adlandırılan:
ID event_id meta_key meta_value
1 1 repeat_start 1299132000
2 1 repeat_interval_1 432000
Repeat_start bir unıx olarak hiçbir zaman bir tarih, ve repeat_interval aralıkları arasında saniye cinsinden miktarı (432000 5 gün) damgası.
repeat_interval_1 KİMLİĞİ 1 repeat_start gider. Eğer her Salı ve her yinelenen bir olay varsa Perşembe, repeat_interval 604800 (7 gün), ve 2 repeat_starts ve 2 repeat_intervals olacaktır. Tablo bu gibi görünecektir:
ID event_id meta_key meta_value
1 1 repeat_start 1298959200 -- This is for the Tuesday repeat
2 1 repeat_interval_1 604800
3 1 repeat_start 1299132000 -- This is for the Thursday repeat
4 1 repeat_interval_3 604800
5 2 repeat_start 1299132000
6 2 repeat_interval_5 1 -- Using 1 as a value gives us an event that only happens once
Eğer her gün, gün için olayları kapma döngüsü bir takvim varsa, bu sorgu, bu gibi görünecektir:
SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
RIGHT JOIN `events_meta` EM2 ON EM2.`meta_key` = CONCAT( 'repeat_interval_', EM1.`id` )
WHERE EM1.meta_key = 'repeat_start'
AND (
( CASE ( 1299132000 - EM1.`meta_value` )
WHEN 0
THEN 1
ELSE ( 1299132000 - EM1.`meta_value` )
END
) / EM2.`meta_value`
) = 1
LIMIT 0 , 30
Unıx {current_timestamp}
yerine geçerli tarih i Zaman, Saat, Dakika ve saniye değerlerini 0 olarak ayarlayın olur) için zaman damgası.
Umarım bu başka biri de yardımcı olacaktır!
Saklama"," Yinelenen Desen . Karmaşık
Bu yöntem, daha karmaşık desenler gibi saklamak için uygundur
Event A repeats every month on the 3rd of the month starting on March 3, 2011
ya
Event A repeats Friday of the 2nd week of the month starting on March 11, 2011
En esneklik için yukarıdaki sistem ile bu birleştirerek tavsiye ederim. Bu tabloları gibi olmalıdır:
ID NAME
1 Sample Event
2 Another Event
Ve bunun gibi bir tablo events_meta
adı:
ID event_id meta_key meta_value
1 1 repeat_start 1299132000 -- March 3rd, 2011
2 1 repeat_year_1 *
3 1 repeat_month_1 *
4 1 repeat_week_im_1 2
5 1 repeat_weekday_1 6
repeat_week_im
1 ve 5 arasında bir potansiyel olabilir, geçerli ay, hafta temsil eder. Haftanın günü, 1-7 repeat_weekday
.
Şimdi hafta/gün takvimde ay görünümü oluşturmak için döngü varsayarak, böyle bir sorgu yazabilirsiniz:
SELECT EV . *
FROM `events` AS EV
JOIN `events_meta` EM1 ON EM1.event_id = EV.id
AND EM1.meta_key = 'repeat_start'
LEFT JOIN `events_meta` EM2 ON EM2.meta_key = CONCAT( 'repeat_year_', EM1.id )
LEFT JOIN `events_meta` EM3 ON EM3.meta_key = CONCAT( 'repeat_month_', EM1.id )
LEFT JOIN `events_meta` EM4 ON EM4.meta_key = CONCAT( 'repeat_week_im_', EM1.id )
LEFT JOIN `events_meta` EM5 ON EM5.meta_key = CONCAT( 'repeat_weekday_', EM1.id )
WHERE (
EM2.meta_value =2011
OR EM2.meta_value = '*'
)
AND (
EM3.meta_value =4
OR EM3.meta_value = '*'
)
AND (
EM4.meta_value =2
OR EM4.meta_value = '*'
)
AND (
EM5.meta_value =6
OR EM5.meta_value = '*'
)
AND EM1.meta_value >= {current_timestamp}
LIMIT 0 , 30
Bu yukarıdaki yöntem en çok tekrarlanan/yinelenen olay örgülerini karşılamak için kombine edilebilir ile birlikte. Eğer bir şey özledim eğer bir yorum bırakın lütfen.
C yükselterek# uzatma yöntemi - çok mu...
Birden çok satır için YİNELENEN KEY UP...
Böyle büyük mükafat 6.4 'Simülatö...
Tüm listeden yinelenen bulmak için nas...
Ruby nasıl yinelenen uzun bir metin di...