SORU
3 Mart 2011, PERŞEMBE


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
3 Mart 2011, PERŞEMBE


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.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Goran Dimov

    Goran Dimov

    1 HAZİRAN 2014
  • ICON

    ICON

    19 EKİM 2011
  • KoreanFrogMania님의 채널

    KoreanFrogMa

    18 Aralık 2011