งานปฏิทินซ้ำ ๆ จะถูกเก็บไว้ในฐานข้อมูลอย่างไร?


14

นี่เป็นโครงการส่วนบุคคลขนาดเล็กสำหรับการจัดการไมโคร โดยทั่วไปฉันเก็บงานไว้ในฐานข้อมูล SQLite3 ที่มีลักษณะดังนี้:

    id INTEGER PRIMARY KEY AUTOINCREMENT
    label TEXT
    deadline INTEGER

ดังนั้นแต่ละงานจึงมีวันครบกำหนด (กำหนดเวลา) ที่จัดเก็บเป็น Unix Time Stamp จนถึงตอนนี้ดีฉันสามารถทำรายการเช่น "พรุ่งนี้: เยี่ยมยาย" และแถวใหม่จะถูกสร้างขึ้นด้วย "เยี่ยมยาย" เป็นป้ายกำกับและในวันพรุ่งนี้จะเปลี่ยนเป็นเวลา Unix สำหรับกำหนดเวลา

ตอนนี้ฉันต้องการป้อนงานประเภทใหม่: งานประจำ - งานที่ทำซ้ำในรูปแบบเวลาเช่น "ทุกวัน: ครัวสะอาด" งานดังกล่าวจะถูกจัดเก็บหรือจำลองอย่างไร

ในขณะนี้ฉันคิดว่าในกรณีของงานที่ต้องทำทุกวันเพื่อสร้างแถวใหม่ในตารางของฉันที่จะมีป้ายกำกับเดียวกันและฟิลด์กำหนดเวลาเพิ่มขึ้นหนึ่งวัน ในกรณีนี้ฉันต้องแก้ไขขีด จำกัด ในอนาคต ตัวอย่างเช่นถ้าฉันสร้างกิจวัตรประจำวันมันจะสร้างแถวใหม่สำหรับทุกวันของปีที่เหลืออยู่

มีวิธีที่ง่ายกว่านี้หรือไม่? ฉันขาดหลักการออกแบบฐานข้อมูลที่ชัดเจนหรือไม่?


3
ใช่. ใช้เครื่องมือตัวกำหนดตารางเวลาที่เหมาะสมแทนการประดิษฐ์ตัวจัดกำหนดการงานอื่น หลังจากที่การประท้วงโสภาปลายอ่านen.wikipedia.org/wiki/Open_Source_Job_Scheduler สิ่งนี้ได้รับการแก้ไขแล้วหลายครั้งแล้ว
S.Lott

ขอบคุณ Lott! ใช่ฉันสงสัยว่ามีทางออกที่ดีสำหรับเรื่องนี้! ฉันจะรอให้ SOPA สิ้นสุดหรือตรวจสอบว่ามีการแปลในประเทศอื่น ๆ ใน Wikipedia แก้ไข: จริง ๆ แล้วฉันเพิ่งสังเกตเห็นว่าแหล่งที่มาของ HTML นั้นยังคงมีอยู่ใน Wikipedia US หน้าจอสีดำออกมาเหมือนกลลวง CSS วิธีสำหรับสคริปต์ greasemonkey ขนาดเล็ก :)
François esp Vespa ت

1
หมายเหตุทั่วไป: โพสต์ด้านล่างส่วนใหญ่ไม่ได้คำนึงถึงคำถามว่ามีการจัดเก็บข้อมูลอย่างไร ฉันหมายถึงให้งานที่ทำซ้ำทุกวันจันทร์เป็นเวลา 2 ปีจะต้องเขียนจำนวนกี่แถวลงดิสก์
NoChance

หรือดูคำตอบนี้
Kris Harper

@ root45 ดีจริงผมใช้แมวป่าชนิดหนึ่งจากบรรทัดคำสั่งง่ายยิ่งขึ้น :)
FrançoisッVespa ت

คำตอบ:


7

คุณสามารถสร้างตารางแยกต่างหากเพื่อให้เกิดซ้ำได้ แต่โดยสุจริตฉันจะใส่ลงในตารางเดียวกันกับ Type Field

บางสิ่งเช่นนี้

ID - Int Pk

TaskDescription - TEXT

Type - Text - (Re-Occurring, or Single Occurrence) 

Due- TimeStamp - for Single Occurrence is the Date time

LastTimeCompleted - Time Stamp

ReoccurringUnit - Text - "Days", Weeks, Month, Ext

ReoccurringEveryX - Int - Reoccurring interval 

ที่น่าสนใจฉันกำลังค้นหาวิธีแก้ปัญหาที่เป็นไปได้คล้ายกับอันนี้ฉันยังคงใช้งานฟังก์ชั่น SQL ของฉันฉันจะโพสต์ถ้าประสบความสำเร็จ
Françoisッ Vespa ت

น่าสนใจฉันกำลังพยายามค้นหาด้วยแบบสอบถามที่สามารถดึงข้อมูลงานที่เกิดซ้ำและไม่เกิดซ้ำแล้วเรียงลำดับตามวันที่ครบกำหนด เบาะแสใด ๆ
Harshal Patil

2

นอกจากความคิดเห็นจาก S.Lott แล้วMartin Fowler - กิจกรรมที่เกิดซ้ำสำหรับปฏิทิน PDF อาจช่วยคุณได้ (ฉันพบว่ามันยากสักหน่อย)

นอกจากนี้โปรดทราบว่าเครื่องมือ UI หลายอย่างมีฟังก์ชั่นที่คุณกำลังอธิบายอยู่นอกกรอบ (พร้อมโมเดลงานง่าย) ฉันจะพิจารณาปัญหานี้ว่ายากที่จะแก้ปัญหาการออกแบบฐานข้อมูลโดยไม่มีเครื่องมือดังกล่าว


1

ในมุมมองของฉันมีสองตัวเลือก:

  • เก็บแถวจำนวนเท่ากันจำนวนมากสำหรับไอเท็มที่ทำให้เกิดรายการซ้ำอย่างไรก็ตามพวกมันจะต้องจบ (ทั้งจนถึงวันที่สิ้นสุดหรือจำนวน จำกัด ของไอเท็ม) และจะต้องทำเครื่องหมายเป็นไอเท็มที่เกิดขึ้นอีก เมื่อคุณเปลี่ยนเหตุการณ์คุณต้องอัปเดตทั้งหมด แต่เมื่อคุณต้องการเบี่ยงเบนเพียงครั้งเดียวคุณสามารถ 'หยุด' การเชื่อมต่อระหว่างเหตุการณ์หนึ่งและทำให้เป็นเหตุการณ์ปกติ
  • เก็บเหตุการณ์เป็นรายการที่เกิดขึ้นซ้ำโดยมีรูปแบบการทำซ้ำบางอย่างและคำนวณสำหรับวันที่ที่กำหนดซึ่งรายการที่เกิดขึ้นซ้ำจะครบกำหนดในวันที่กำหนด สิ่งนี้ให้ความเป็นไปได้สำหรับการทำซ้ำไม่สิ้นสุด

นั่นเป็นวิธีที่ฉันเห็นเช่นกัน
Françoisッ Vespa ت

1

ถ้านี่เป็นโครงการส่วนบุคคลและคุณต้องการเพียงแค่วิธีการเก็บงานของคุณผมขอแนะนำTaskCoach มันเป็นแอพพลิเคชั่นเดสก์ท็อปหลายแพลตฟอร์มโอเพ่นซอร์สเริ่มต้นใช้งานง่ายและมีคุณสมบัติที่ดีจริงๆ

ในกรณีที่คุณกำลังพัฒนาแอปพลิเคชันงานวิธีที่น่าจะเป็นไปได้มากที่สุดคือการเพิ่มแถวใหม่สำหรับแต่ละงานที่เกิดซ้ำ เหตุผลก็คือว่าแต่ละงานเป็นนิติบุคคลที่แยกต่างหากในตัวเองและจะต้องเสร็จสิ้นก่อนที่จะเริ่มงานเดียวกันในวันถัดไป หากคุณเพิ่มขึ้นคุณจะไม่สามารถบันทึกประวัติของงานได้

ในกรณีที่คุณรู้สึกว่ามันจะให้รายการใหญ่ถ้าคุณทำไม่กี่งานเสร็จแล้วคุณสามารถทริกเกอร์เหตุการณ์เมื่องานที่เกิดซ้ำเสร็จสมบูรณ์เพื่อให้งานใหม่ถูกสร้างขึ้นเป็นแถวใหม่เฉพาะเมื่องานเป็น ทำเครื่องหมายว่าเสร็จสมบูรณ์ ตามที่ Morons แนะนำคุณสามารถใช้ตารางแยกต่างหากพร้อมกับการตั้งค่าสถานะสำหรับงานที่เกิดซ้ำในตารางเดิมพร้อมกับข้อมูลสำหรับการเกิดซ้ำ (วัน, สัปดาห์, เวลาเกิดซ้ำ) เพื่อให้คุณสามารถมีสคริปต์ง่าย ๆ ที่สามารถสร้างงานที่เกิดขึ้นประจำ วันที่หรือเงื่อนไขหรือตามฉลาก

แต่ถ้าคุณแน่ใจว่างานนั้นเป็นงานที่ทำซ้ำ ๆ อย่างแน่นอนโดยไม่มีการเปลี่ยนแปลงใด ๆ (เช่นแปรงทุกวัน) และไม่ต้องการการติดตามที่กว้างขวางคุณสามารถลองใช้โครงสร้างต่อไปนี้

  • สถานะการเกิดซ้ำ - เพื่อระบุว่างานเกิดซ้ำ
  • เกิดซ้ำระยะเวลา - วัน, สัปดาห์, เดือน
  • จำนวนงานที่สร้างขึ้น - สิ่งนี้จะเพิ่มงานตามระยะเวลาที่เกิดขึ้นอีก ดังนั้นหากงานเริ่มต้นในวันนี้และมีระยะเวลาเกิดขึ้นอีกหนึ่งวันมันก็จะเพิ่มขึ้นในวันพรุ่งนี้
  • จำนวนงานที่เสร็จสมบูรณ์ - สิ่งนี้จะเพิ่มขึ้นหากงานเสร็จสมบูรณ์

ตรรกะคือความแตกต่างระหว่างงานที่เสร็จสมบูรณ์และงานที่สร้างขึ้นควรจะเป็นช่วงเวลาที่เกิดขึ้นอีกหากงานนั้นเสร็จสมบูรณ์เสมอ ดังนั้นการหารความแตกต่างของวันตามช่วงเวลาที่เกิดขึ้นอีกจะทำให้คุณทราบว่างานค้างอยู่นานเท่าไหร่

ขอบคุณสำหรับ Kareem ที่ชี้เรื่องนี้ออกมา

IMHO แอปพลิเคชันงานสร้างได้ยากสำหรับคนส่วนใหญ่


ขอบคุณสำหรับคำตอบที่สร้างสรรค์! นี่เป็นโครงการเพื่อความสนุกและฉันต้องการทำให้ยืดหยุ่นที่สุดเท่าที่จะเป็นไปได้โดยมีคำสั่งเช่น 'ให้ทำซ้ำทุก ๆ 4 วันยกเว้นว่าเป็นวันพุธ'
Françoisッ Vespa ت

1

การดำเนินการที่บ่อยที่สุดคือการแสดงรายการเหตุการณ์ทั้งหมดที่เกิดขึ้นในช่วงเวลาหนึ่ง ดังนั้นปรับข้อมูลของคุณให้เหมาะสมเพื่อให้คำถามนั้นสามารถตอบได้ด้วยแบบสอบถาม SQL อย่างง่าย ฉันจะสร้างสองตาราง:

CREATE TABLE events(start TIMESTAMP, end TIMESTAMP, name TEXT, user_id LONG,
                    recurrence_id LONG, ...);
CREATE TABLE recurrences(id LONG, start TIMESTAMP, end TIMESTAMP, name TEXT, 
                         frequency ...);

จัดทำดัชนีตารางเหตุการณ์ตามเวลาเริ่มต้นและสิ้นสุด จากนั้นแบบสอบถามทั้งหมดสามารถตอบได้จากตารางกิจกรรมอย่างรวดเร็ว เมื่อแก้ไขการเกิดซ้ำเพียงลบและสร้างเหตุการณ์ที่เกี่ยวข้องทั้งหมดใหม่

คำแนะนำนี้ซ้ำอีกครั้งอย่างไร้ยางอายจากหนังสือโดย Tom Kite


1

งานที่ทำซ้ำควรมีวันที่เริ่มต้นและวันที่สิ้นสุด สำหรับงานวันที่เดียวพวกเขาจะเป็นวันที่เดียวกัน

สร้างตาราง "วันที่" ที่มีหนึ่งระเบียนสำหรับทุกวันที่คุณคิดว่าเกี่ยวข้องกับจุดเริ่มต้นของความต้องการของคุณจนถึงอนาคตตามที่คุณต้องการ: ตัวอย่างเช่น 12/31/2100 และแปลงเป็นรูปแบบของคุณ

แบบสอบถามอาจมีลักษณะดังนี้:

Select 
  t.id
  , t.label
  , d.UnixDate
from Tasks as t
inner join Dates as d
on d.UnixDate >= t.StartDate
  and d.UnixDate <= t.EndDate
where t.id = [ID Param]

0

ฉันได้ทำสิ่งที่คล้ายกันหลายปีที่ผ่านมาการใช้อินเทอร์เฟซเช่น Windows Task Scheduler และโดยทั่วไปสำหรับแต่ละงานที่คุณมี StartDate, EndDate (อาจเป็นโมฆะ), StartTime และ RecurringDays ที่มีวันในสัปดาห์ที่ต้องจัดตารางงาน


นั่นดูน่าสนใจ. มีข้อ จำกัด ในการออกแบบบ้างหรือไม่เช่นแบบสอบถามที่ไม่สามารถทำได้ (เช่น 'ทำซ้ำทุกวัน')
Françoisッ Vespa ت

0

คุณสามารถใช้สองตาราง: หนึ่งรายการสำหรับคำอธิบายของงานอื่น ๆ สำหรับสถานะของพวกเขา (เสร็จแล้ว / ไม่ได้ทำและข้อมูลอื่น ๆ : เวลาที่ใช้สถานะออกจากที่ตั้งของไฟล์บันทึก ฯลฯ ) ตารางคำอธิบายจะประกอบด้วย ชื่อของงานและวันที่หรือความถี่ที่ควรรัน: จะมีเพียงหนึ่งแถวต่องาน ทุกวันกระบวนการจะเติมตารางสถานะสำหรับงานที่ต้องทำในวันนี้จากตารางคำอธิบาย (คุณสามารถเติมหนึ่งสัปดาห์หรือหนึ่งเดือนล่วงหน้า)

การสร้างตารางสถานะโดยทางโปรแกรมให้ความยืดหยุ่นทั้งหมดที่คุณต้องการสำหรับความถี่ (เช่น "ทุกวันทำงานยกเว้นวันหยุดธนาคารสำหรับประเทศ X" - มันอาจถูกเก็บไว้เป็นสตริง) การมีตารางสถานะอนุญาตให้คุณตรวจสอบว่างานล้มเหลวหรือไม่ (ตัวอย่างเช่น: "ฉันควรจะทำงานทุกวัน: ฉันมีเวลาทำบ่อยแค่ไหน?")

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.