2011-09-05 28 views
7

Tôi đang xây dựng hệ thống lịch từ đầu (yêu cầu, vì tôi đang làm việc với một loại lịch đặc biệt cùng với Gregorian) và tôi cần trợ giúp về logic . Tôi đang viết ứng dụng trong Django và Python.Lặp lại "sự kiện" trong lịch: CPU và Cơ sở dữ liệu

Về cơ bản, các vấn đề logic mà tôi đang gặp phải là cách duy trì càng ít đối tượng càng tốt càng tốt càng tốt mà không cần chạy tab trên chu kỳ CPU. Tôi cảm thấy rằng đa hình sẽ là một giải pháp cho điều này, nhưng tôi không chắc chắn làm thế nào để thể hiện nó ở đây.

Tôi có hai tập hợp cơ bản của sự kiện, lặp lại sự kiện và sự kiện một lần.

Sự kiện lặp lại sẽ có người đăng ký, những người được thông báo về những thay đổi của họ. Ví dụ, nếu một lớp học bị hủy bỏ hoặc chuyển đến một địa chỉ hoặc thời gian khác, những người đã đăng ký cần phải biết về điều này. Một số sự kiện chỉ diễn ra hàng ngày cho đến cuối thời gian, sẽ không được chỉnh sửa và "chỉ xảy ra". Vấn đề là nếu tôi có một đối tượng lưu trữ thông tin sự kiện và chính sách lặp lại của nó, thì việc hủy hoặc sửa đổi một sự kiện trong chuỗi thực sự sẽ làm mọi thứ trở nên khó khăn hơn. thay đổi và giữ cho chuỗi thành một nhóm hợp lý.

Nghịch lý: tạo các đối tượng sự kiện duy nhất cho mỗi sự kiện bình thường trong chuỗi cho đến khi kết thúc thời gian (nếu lặp lại vô thời hạn) không có ý nghĩa nếu tất cả chúng đều lưu trữ cùng một thông tin; tuy nhiên, nếu có bất kỳ thay đổi nào xảy ra với một sự kiện trong chuỗi, tôi sẽ gần như để tạo một đối tượng khác trong cơ sở dữ liệu để biểu thị hủy.

Ai đó có thể giúp tôi với logic ở đây không? Nó thực sự làm tôi suy nghĩ và tôi không thể nghĩ thẳng được nữa. Tôi thực sự thích một số đầu vào về cách giải quyết vấn đề này, vì các sự kiện lặp lại không chính xác là điều hợp lý dễ nhất (lặp lại mỗi ngày khác, hoặc mỗi M/W/F hoặc vào ngày m đầu tiên của mỗi tháng hoặc 3 tháng một lần, hoặc mỗi năm một lần vào ngày này, hoặc mỗi tuần một lần vào ngày này, hoặc mỗi tháng một lần vào ngày này, hoặc lúc 9:00 sáng vào các ngày thứ Ba và 11:00 sáng vào thứ Năm, vv) và tôi muốn giống như giúp hiểu đường logic tốt nhất cho các sự kiện lặp lại.

Dưới đây là một suy nghĩ về làm thế nào để làm điều đó:

class EventSeries(models.Model): 
    series_name = models.TextField() 
    series_description = models.TextField() 
    series_repeat_policy = models.IHaveNoIdeaInTheWorldOnHowToRepresentThisField() 
    series_default_time = models.TimeField() 
    series_start_date = models.DateField() 
    series_end_date = models.DateField() 
    location = models.ForeignKey('Location') 

class EventSeriesAnomaly(models.Model): 
    event_series = models.ForeignKey('EventSeries', related_name="exceptions") 
    override_name = models.TextField() 
    override_description = models.TextField() 
    override_time = models.TimeField() 
    override_location = models.ForeignKey('Location') 
    event_date = models.DateField() 

class EventSeriesCancellation(models.Model): 
    event_series = models.ForeignKey('EventSeries', related_name="cancellations") 
    event_date = models.TimeField() 
    cancellation_explanation = models.TextField() 

Điều này dường như làm cho một chút cảm giác, nhưng như đã nói ở trên, điều này được làm hỏng não của tôi ngay bây giờ để bất cứ điều gì có vẻ như nó sẽ làm việc. (Một vấn đề và câu hỏi khác, nếu ai đó muốn sửa đổi tất cả các sự kiện còn lại trong chuỗi, tôi phải làm gì!) Tôi cho rằng tôi có thể thay đổi 'series_default_time' và sau đó tạo ra các thể hiện bất thường cho tất cả các trường hợp trước đây để đặt chúng đến thời điểm ban đầu, nhưng AHHHHHH !!!)

sôi nó xuống đến ba, câu hỏi bê tông đơn giản, ta có:

  1. Làm thế nào tôi có thể có một loạt các sự kiện lặp đi lặp lại, chưa cho phép hủy bỏ và sửa đổi trên các sự kiện riêng lẻ sửa đổi trên toàn bộ phần còn lại của chuỗi, trong khi lưu trữ ít đối tượng trong cơ sở dữ liệu là hoàn toàn cần thiết, không bao giờ tạo đối tượng cho các sự kiện riêng lẻ trong nâng cao?
  2. Làm cách nào tôi có thể lặp lại các sự kiện theo cách có thể tùy chỉnh cao mà không làm mất suy nghĩ, để tôi có thể cho phép sự kiện lặp lại trong number of ways, nhưng lại làm mọi thứ trở nên dễ dàng và lưu trữ càng ít đối tượng càng tốt?
  3. Làm cách nào tôi có thể thực hiện tất cả những điều trên, cho phép chuyển đổi trên mỗi chuỗi sự kiện để nó không xảy ra nếu nó rơi ra trên holiday?
+5

+1 cho lớp hiếm thấy nhưng luôn hữu ích như vậy: models.IHaveNoIdeaInTheWorldOnHowToRepresentThisField – mjhm

+0

Tôi sử dụng trường đó quá thường xuyên. –

Trả lời

1

Tôi muốn chỉ giải quyết câu hỏi 3, về ngày lễ.

Trong một số cơ sở dữ liệu báo cáo, tôi thấy thuận tiện để xác định bảng, hãy gọi nó là "Almanac", có một hàng cho mỗi ngày, trong một phạm vi nhất định. Nếu phạm vi kéo dài mười năm, bảng sẽ chứa khoảng 3.652 hàng. Đó là nhỏ theo tiêu chuẩn ngày nay. Khóa chính là ngày tháng.

Một số cột khác là những thứ như ngày là ngày nghỉ, ngày làm việc bình thường hay ngày cuối tuần. Tôi biết, tôi biết, bạn có thể tính toán các công cụ cuối tuần bằng cách sử dụng một chức năng được xây dựng trong.Nhưng hóa ra lại thuận tiện để bao gồm công cụ này làm dữ liệu. Nó làm cho việc tham gia của bạn đơn giản và giống nhau hơn.

Sau đó, bạn có một chương trình ứng dụng phổ biến Almanac. Nó có tất cả các quirks lịch được xây dựng vào nó, bao gồm các quy tắc doanh nghiệp để tìm ra ngày nào là ngày lễ. Thậm chí bạn có thể bao gồm các cột có "tháng tài chính" mà một ngày cụ thể thuộc về, nếu có liên quan đến trường hợp của bạn. Phần còn lại của ứng dụng, cả hai chương trình nhập và chương trình trích xuất, tất cả đều coi Almanac giống như dữ liệu cũ thuần túy.

Điều này có vẻ kém tối ưu do không tối thiểu. Nhưng hãy tin tôi, mẫu thiết kế này rất hữu ích trong nhiều tình huống khác nhau. Nó tùy thuộc vào bạn để tìm ra cách nó áp dụng cho trường hợp của bạn.

Almanac thực sự là tập con của các nguyên tắc lưu trữ dữ liệu và thiết kế lược đồ hình sao.

nếu bạn muốn làm điều tương tự bên trong CPU, bạn có thể có đối tượng "Almanac" với các tính năng công khai như Almanac.holiday (ngày).

+0

Đối với trường hợp sử dụng này, điều này rất có ý nghĩa. Kể từ những ngày nghỉ tôi tính toán được tính toán bằng cách sử dụng logic hơi phức tạp (chúng tôi không giao dịch với lịch Gregorian ở đây), điều này có thể là một ý tưởng tốt trong trường hợp sử dụng này. Vì các loại đối tượng này sẽ không thể chỉnh sửa được và có thể được lưu vào bộ nhớ cache, điều này có ý nghĩa. Tôi có thể sẽ tạo ra hai bảng, một cho các ngày lập bản đồ từ lịch của tôi đến Gregorian, cái kia để lập bản đồ ngày lễ cho các ngày của lịch của tôi, và sau đó tôi sẽ tìm cách kết hợp dữ liệu và thông minh. Cảm ơn. –

+0

Vâng. Một trong các cột trong Alamanac của bạn sẽ có vẻ là ngày tương đương được thể hiện, tuy nhiên lịch của bạn thể hiện ngày tháng. Sau đó, bạn có thể recoord ngày của các sự kiện và tương tự trong ngày gregorian đồng bằng cũ, giống như DBMS hiểu, nhưng tham gia nó với niên giám để trình bày ngày trong lịch của bạn cho người sử dụng dữ liệu của bạn. –

0

Tôi phải đối mặt với cùng một vấn đề giống như bạn trước đây. Tuy nhiên, giải pháp ban đầu không chứa bất kỳ sự bất thường hoặc hủy bỏ nào, chỉ lặp lại các sự kiện. Cách chúng tôi mô hình hóa một loạt các sự kiện lặp lại, là có một số trường cho biết loại khoảng thời gian (như hàng tháng/hàng tuần/hàng ngày) và sau đó là khoảng cách (như mỗi ngày thứ 2, tuần thứ 2, v.v.) bắt đầu từ một ngày bắt đầu nhất định . Cách lặp lại đơn giản này không bao gồm quá nhiều kịch bản, nhưng rất dễ tính toán các ngày lặp lại. Các cách lặp lại khác cũng có thể xảy ra, ví dụ như một cái gì đó theo cách cronjobs được xác định.

Để tạo lặp lại, chúng tôi đã tạo một hàm bảng, cho một số userid tạo tất cả các sự kiện lặp lại khi đang bay lên đến 5 năm tương lai khi đang sử dụng SQL đệ quy (như trong cách tiếp cận của bạn, cho một tập hợp các lần lặp lại, chỉ một sự kiện phải được lưu trữ). Điều này cho đến nay hoạt động rất tốt và chức năng bảng có thể được truy vấn như thể các sự lặp lại riêng lẻ thực sự được lưu trữ trong cơ sở dữ liệu. Nó cũng có thể dễ dàng mở rộng để loại trừ bất kỳ sự kiện bị hủy và thay thế các sự kiện đã thay đổi dựa trên ngày tháng, cũng trên bay. Tôi không biết nếu điều này là có thể với cơ sở dữ liệu của bạn và ORM của bạn.

+0

Nó không phải là quá có thể xảy ra (cho trường hợp sử dụng của tôi), vì tôi thực sự cần phải tồn tại như vài đối tượng như con người có thể. Tôi không thực sự nhìn thấy điểm trong sự bền bỉ của rất nhiều đối tượng nếu bởi một số bước ngoặt của logic tôi có thể đưa ra một giải pháp mà chỉ liên quan đến một vài. Tôi càng nghĩ về nó, mô hình dữ liệu tôi đã viết có vẻ tốt hơn (cái ở trên), nhưng tôi vẫn cần phải có một cách linh hoạt để xử lý các sự lặp lại phức tạp, vì vậy tôi nghĩ rằng tôi cần một mô hình khác để biểu diễn các sự lặp lại biến thể. –

+0

Huh? Những gì bạn có nghĩa là có thể xảy ra? Và tôi không thấy làm thế nào bạn có thể có ít kiên trì hơn này, có lẽ tôi đã không giải thích rõ ràng đủ. –

3

Điều này có thể trở thành một cuộc thảo luận nóng, vì logic ngày thường là khó hơn nhiều so với giao diện đầu tiên và mọi người sẽ có ý tưởng riêng về cách thực hiện mọi thứ.

Tôi có thể hy sinh một số không gian db và có các mô hình càng câm càng tốt (ví dụ: không phải xác định dị thường cho một chuỗi). Các điều kiện lặp lại có thể là một số thuật ngữ đơn giản mà sẽ phải được phân tích cú pháp (tùy thuộc vào yêu cầu của bạn) hoặc - KISS - chỉ là khoảng thời gian sự kiện tiếp theo xảy ra. Từ đây, bạn có thể tạo sự kiện "tiếp theo", sẽ sao chép điều kiện lặp lại và bạn tạo nhiều sự kiện trong tương lai khi cần thiết (xác định một số cửa sổ thời gian tối đa trong tương lai để tạo sự kiện nhưng tạo họ chỉ, khi ai đó trong thực tế nhìn vào thời gian intervall trong câu hỏi). Các sự kiện có thể có một con trỏ trở lại sự kiện cha mẹ của nó, do đó, một chuỗi toàn bộ có thể nhận dạng (giống như một danh sách liên kết).

Mô hình phải có chỉ báo, liệu một sự kiện có bị hủy hay không. (Sự kiện vẫn còn trong db, để có thể sao chép sự kiện vào tương lai). Hủy bỏ toàn bộ chuỗi sẽ xóa danh sách các sự kiện.

EDIT: other answers đã đề cập đến the dateutil package để xây dựng và phân tích theo khoảng thời gian, trông thực sự rất đẹp.

+0

+1 cho dateutil. 'rrule' và' rruleset' có vẻ như chúng hữu ích ở đây. – sandinmyjoints

1

Đối với một mô hình hàng loạt sự kiện tôi tạo ra, giải pháp của tôi để IHaveNoIdeaInTheWorldOnHowToRepresentThisField là sử dụng pickled object field để cứu một quy tắc tái phát (rrule) từ dateutil trong mô hình chuỗi sự kiện của tôi.

Các vấn đề liên quan