Database
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Database

Lặp đi lặp lại! Quản lý các sự kiện định kỳ trong mô hình dữ liệu

Sự kiện lặp lại, theo định nghĩa, là một sự kiện lặp lại trong một khoảng thời gian; nó còn được gọi là sự kiện định kỳ. Có nhiều ứng dụng cho phép người dùng của họ thiết lập các sự kiện lặp lại. Hệ thống cơ sở dữ liệu quản lý các sự kiện lặp lại như thế nào? Trong bài viết này, chúng ta sẽ khám phá một cách xử lý chúng.

Việc tái diễn không dễ dàng đối với các ứng dụng. Nó có thể trở thành một nhiệm vụ bão táp, đặc biệt là khi đề cập đến mọi tình huống lặp lại có thể xảy ra - bao gồm tạo các sự kiện hai tuần hoặc hàng quý hoặc cho phép lên lịch lại tất cả các trường hợp sự kiện trong tương lai.

Hai cách để quản lý các sự kiện định kỳ

Tôi có thể nghĩ ra ít nhất hai cách để xử lý các tác vụ định kỳ trong một mô hình dữ liệu. Trước khi chúng ta thảo luận về chúng, hãy nhanh chóng xem qua các yêu cầu của nhiệm vụ này. Tóm lại, quản lý hiệu quả có nghĩa là:

  • Người dùng được phép tạo các sự kiện thường xuyên và định kỳ.
  • Có thể tạo các sự kiện hàng ngày, hàng tuần, hai tuần, hàng tháng, hàng quý, hai năm một lần và hàng năm mà không có hạn chế về ngày kết thúc.
  • Người dùng có thể lên lịch lại hoặc hủy một phiên bản sự kiện hoặc tất cả các phiên bản sự kiện trong tương lai.

Xem xét các tham số này, có hai cách để quản lý các sự kiện lặp lại trong mô hình dữ liệu. Chúng tôi sẽ gọi họ theo cách ngây thơ và cách chuyên gia.

Con đường ngây thơ: Lưu trữ tất cả các trường hợp lặp lại có thể có của một sự kiện dưới dạng các hàng riêng biệt trong bảng. Trong giải pháp này, chúng tôi chỉ yêu cầu một bảng, đó là event . Bảng này có các cột như event_title , start_date , end_date , is_full_day_event , v.v. start_dateend_date cột là kiểu dữ liệu dấu thời gian; theo cách này, họ có thể tổ chức các sự kiện không kéo dài cả ngày.

Ưu điểm: Đây là một cách tiếp cận khá đơn giản và đơn giản nhất để thực hiện.

Nhược điểm: Cách làm ngây thơ có một số nhược điểm đáng kể, bao gồm:

  • Sự cần thiết phải lưu trữ tất cả các trường hợp có thể có của một sự kiện. Nếu bạn đang tính đến nhu cầu của một cơ sở người dùng lớn thì cần phải có một lượng lớn dung lượng. Tuy nhiên, mặt bằng khá rẻ nên điểm này không ảnh hưởng nhiều.
  • Quá trình cập nhật rất lộn xộn. Giả sử một sự kiện được lên lịch lại. Trong trường hợp đó, ai đó phải cập nhật tất cả các phiên bản của nó. Cần phải thực hiện một số lượng lớn các thao tác DML khi lên lịch lại, điều này tạo ra tác động tiêu cực đến hiệu suất ứng dụng.
  • Xử lý các trường hợp ngoại lệ. Tất cả các trường hợp ngoại lệ phải được xử lý một cách khéo léo, đặc biệt nếu bạn phải quay lại và chỉnh sửa cuộc hẹn ban đầu sau khi thực hiện một ngoại lệ. Ví dụ:giả sử bạn di chuyển phiên bản thứ ba của một sự kiện lặp lại trước một ngày. Điều gì sẽ xảy ra nếu sau đó bạn chỉnh sửa thời gian của sự kiện ban đầu? Bạn có chèn lại một sự kiện khác vào ngày ban đầu và để lại sự kiện bạn đã đưa ra trước không? Bỏ liên kết ngoại lệ? Cố gắng thay đổi nó một cách thích hợp?
  • Cách chuyên gia: Lưu trữ một mẫu lặp lại và tạo các trường hợp sự kiện trong quá khứ và tương lai theo lập trình. Giải pháp này giải quyết những mặt trái của giải pháp ngây thơ. Chúng tôi sẽ giải thích chi tiết về giải pháp của chuyên gia trong bài viết này.

    Mô hình được đề xuất




    Tạo sự kiện

    Tất cả các sự kiện đã lên lịch, bất kể tính chất thường xuyên hay định kỳ của chúng, đều được đăng nhập vào event bàn. Không phải tất cả các sự kiện đều là sự kiện lặp lại, vì vậy chúng tôi sẽ cần một cột gắn cờ, is_recurring , trong bảng này để chỉ định rõ ràng các sự kiện lặp lại. event_titleevent_description các cột lưu trữ chủ đề và một bản tóm tắt ngắn gọn về các sự kiện. Mô tả sự kiện là tùy chọn, đó là lý do tại sao cột này không có giá trị.

    Như tên của chúng gợi ý, start_dateend_date cột giữ ngày bắt đầu và ngày kết thúc của các sự kiện. Trong trường hợp các sự kiện thông thường, các cột này lưu trữ ngày bắt đầu và ngày kết thúc thực tế. Tuy nhiên, chúng cũng lưu trữ ngày của lần xuất hiện đầu tiên và lần cuối cùng của các sự kiện định kỳ. Chúng tôi sẽ giữ end_date cột là nullable, vì người dùng có thể định cấu hình các sự kiện lặp lại không có ngày kết thúc. Trong trường hợp này, các lần xuất hiện trong tương lai cho đến ngày kết thúc giả định (giả sử trong một năm) sẽ được hiển thị trong giao diện người dùng.

    is_full_date_event cột biểu thị nếu một sự kiện là một sự kiện cả ngày. Trong trường hợp sự kiện diễn ra cả ngày, start_timeend_time các cột sẽ rỗng; đó là lý do để giữ cho cả hai cột này đều không có giá trị.

    created_bycreated_date các cột lưu trữ người dùng nào đã tạo sự kiện và ngày tạo sự kiện.

    Tiếp theo là parent_event_id cột. Điều này đóng một vai trò quan trọng trong mô hình dữ liệu của chúng tôi. Tôi sẽ giải thích ý nghĩa của nó ở phần sau.

    Quản lý các lần lặp lại

    Bây giờ chúng ta đi thẳng vào tuyên bố vấn đề chính:Điều gì sẽ xảy ra nếu một sự kiện lặp lại được tạo trong event bảng - tức là is_recurring cờ cho sự kiện là “Y”?

    Như đã giải thích trước đó, chúng tôi sẽ lưu trữ một mẫu lặp lại cho các sự kiện để chúng tôi có thể xây dựng tất cả các lần xuất hiện trong tương lai của nó. Hãy bắt đầu bằng cách tạo recurring_pattern bàn. Bảng này có các cột sau:

    • Event_id - Cột này được tham chiếu từ event và nó đóng vai trò là khóa chính trong bảng này. Nó cho thấy mối quan hệ xác định giữa eventrecurring_pattern những cái bàn. Cột này cũng sẽ đảm bảo rằng có tối đa một mẫu lặp lại tồn tại cho mỗi sự kiện.
    • Recurring_type_id - Cột này biểu thị loại lặp lại, cho dù đó là hàng ngày, hàng tuần, hàng tháng hay hàng năm.
    • Max_num_of_occurrances - Có những lúc chúng ta không biết chính xác ngày kết thúc cho một sự kiện nhưng chúng ta biết cần bao nhiêu lần (cuộc họp) để hoàn thành nó. Cột này lưu trữ một số tùy ý xác định kết thúc logic cho một sự kiện.
    • Separation_count - Bạn có thể tự hỏi làm thế nào có thể định cấu hình sự kiện hai tuần hoặc hai năm một lần nếu chỉ có bốn giá trị kiểu lặp lại có thể có (hàng ngày, hàng tuần, hàng tháng, hàng năm). Câu trả lời là separation_count cột. Cột này biểu thị khoảng thời gian (tính bằng ngày, tuần hoặc tháng) trước khi trường hợp sự kiện tiếp theo được phép. Ví dụ:nếu một sự kiện cần được định cấu hình cách tuần một lần, thì split_count =“1” để đáp ứng yêu cầu này. Giá trị mặc định cho cột này là “0”.

    Hãy xem xét tầm quan trọng của các cột còn lại theo các loại định kỳ khác nhau.

    Lặp lại hàng ngày

    Chúng ta có thực sự cần nắm bắt một mẫu cho một sự kiện lặp lại hàng ngày không? Không, bởi vì tất cả các chi tiết cần thiết để tạo mẫu lặp lại hàng ngày đã được đăng nhập trong event bảng.

    Kịch bản duy nhất yêu cầu một mẫu là khi các sự kiện được lên lịch cho các ngày thay thế hoặc mỗi X số ngày. Trong trường hợp này, separation_count cột sẽ giúp chúng tôi hiểu mô hình lặp lại và tìm ra các trường hợp khác.

    Lặp lại hàng tuần

    Chúng tôi chỉ yêu cầu một cột bổ sung, day_of_week , để lưu trữ sự kiện này sẽ diễn ra vào ngày nào trong tuần. Giả sử Thứ Hai là ngày đầu tiên trong tuần và Chủ Nhật là ngày cuối cùng, các giá trị có thể có sẽ là 1,2,3,4,5,6 và 7. Các thay đổi thích hợp trong mã tạo ra các lần xuất hiện sự kiện riêng lẻ nên được thực hiện khi cần thiết. Tất cả các cột còn lại sẽ trống cho các sự kiện hàng tuần.

    Hãy xem một loại sự kiện hàng tuần cổ điển:sự kiện diễn ra hai tuần một lần. Trong trường hợp này, chúng tôi sẽ nói rằng nó xảy ra mỗi tuần luân phiên vào thứ Ba, ngày thứ hai trong tuần. Vì vậy:

    • recurring_type_id sẽ là "hàng tuần".
    • separation_count sẽ là “1”.
    • day_of_week sẽ là “2”.

    Lặp lại hàng tháng

    Bên cạnh day_of_week , chúng tôi yêu cầu thêm hai cột để đáp ứng mọi tình huống lặp lại hàng tháng. Tóm lại, các cột này là:

    • Week_of_month - Cột này dành cho các sự kiện được lên lịch cho một tuần nhất định trong tháng - tức là từ đầu tháng) hoặc -1, -2, -3, ... (tính từ cuối tháng).
    • Day_of_month - Có những trường hợp khi một sự kiện được lên lịch vào một ngày cụ thể trong tháng, chẳng hạn như ngày 25. Cột này đáp ứng yêu cầu này. Giống như week_of_month , nó có thể được điền bằng số dương (“7” cho ngày thứ 7 kể từ đầu tháng) hoặc số âm (“-7” cho ngày thứ bảy kể từ cuối tháng).

    Bây giờ chúng ta hãy xem xét một ví dụ phức tạp hơn - một sự kiện hàng quý. Giả sử một công ty lên lịch cho sự kiện dự báo kết quả hàng quý vào 11 ngày của tháng đầu tiên trong mỗi quý (thường là tháng 1, 4, 7 và 10). Vì vậy, trong trường hợp này:

    • recurring_type_id sẽ là "hàng tháng".
    • separation_count sẽ là “2”.
    • day_of_month sẽ là “11”.
    • Tất cả các cột còn lại sẽ là trống.

    Trong ví dụ trên, chúng tôi giả định rằng người dùng đang tạo dự báo kết quả hàng quý vào tháng Giêng. Xin lưu ý rằng logic phân tách này sẽ bắt đầu tính từ tháng, tuần hoặc ngày khi sự kiện được tạo.

    Trên các dòng tương tự, các sự kiện diễn ra trong nửa năm có thể được ghi lại dưới dạng các sự kiện hàng tháng với separation_count trong tổng số “5”.

    Lặp lại hàng năm

    Sự tái diễn hàng năm là khá đơn giản. Chúng tôi có các cột cho các ngày cụ thể trong tuần và tháng, vì vậy chúng tôi chỉ yêu cầu một cột bổ sung cho tháng trong năm. Chúng tôi đã đặt tên cho cột này là month_of_year .

    Xử lý các trường hợp ngoại lệ của các sự kiện lặp lại

    Bây giờ chúng ta hãy đến với các trường hợp ngoại lệ. Điều gì sẽ xảy ra nếu một trường hợp cụ thể của một sự kiện lặp lại bị hủy bỏ hoặc lên lịch lại? Tất cả các trường hợp như vậy được ghi lại riêng biệt trong event_instance_exception bàn.

    Hãy xem qua hai cột, Is_rescheduledis_cancelled . Các cột này biểu thị liệu phiên bản này có được lên lịch lại vào ngày / giờ muộn hơn hay bị hủy hoàn toàn. Tại sao tôi có hai cột riêng biệt cho việc này? Chà, chỉ cần nghĩ về các sự kiện lần đầu tiên được lên lịch và sau đó bị hủy hoàn toàn. Điều này xảy ra và chúng tôi có một cách để ghi lại nó với các cột này.

    Ngoài hai cột này, tất cả các cột còn lại hoạt động giống như trong event bảng.

    Tại sao lại liên kết hai sự kiện bằng parent_event_id ?

    Có những ứng dụng cho phép người dùng lên lịch lại tất cả các trường hợp sự kiện lặp lại trong tương lai. Trong những trường hợp như vậy, chúng tôi có hai lựa chọn. Chúng tôi có thể lưu trữ tất cả các phiên bản trong tương lai trong event_instance_exception (gợi ý:không phải là một giải pháp chấp nhận được). Hoặc chúng ta có thể tạo sự kiện mới với các thông số ngày / giờ mới trong event và liên kết nó với sự kiện trước đó (sự kiện mẹ) bằng id_parent_event cột.

    Với giải pháp này, chúng tôi có thể nhận được tất cả các lần xuất hiện trong quá khứ của một sự kiện, ngay cả khi mô hình lặp lại của nó đã được thay đổi.

    Làm cách nào để cải thiện việc xử lý sự kiện định kỳ?

    Có một số lĩnh vực phức tạp hơn xung quanh các sự kiện lặp lại mà chúng tôi chưa thảo luận. Đây là hai:

    • Sự kiện diễn ra vào ngày lễ. Khi một trường hợp cụ thể của một sự kiện xảy ra vào ngày nghỉ lễ, sự kiện đó có nên tự động được chuyển sang ngày làm việc ngay sau ngày lễ không? Hay nó nên được tự động hủy bỏ? Trong những trường hợp nào thì một trong hai điều này sẽ áp dụng?
    • Xung đột giữa các sự kiện. Điều gì sẽ xảy ra nếu một số sự kiện nhất định (loại trừ lẫn nhau) rơi vào cùng một ngày?

    Chúng ta cần thực hiện những thay đổi nào để xây dựng những khả năng này? Hãy cho chúng tôi biết quan điểm của bạn trong phần bình luận.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kết nối Snowflake DB &IRI Workbench

  2. Bộ vấn đề 2 - Xác định các thực thể và thuộc tính

  3. Câu lệnh SQL DROP TABLE và các trường hợp sử dụng khác nhau

  4. Thiết kế Cơ sở dữ liệu cho Hệ thống Tuyển dụng

  5. Tôi có nên sử dụng KHÔNG VÀO, ÁP DỤNG NGOÀI TRỜI, TRÁI THAM GIA NGOÀI TRỜI, NGOẠI LỆ, hay KHÔNG TỒN TẠI?