I am creating a booking management system in which it is allowed to create recurrent events.
Searching around, I understood that creating "repeating patters" would be an optimal idea for the DB design, as explained here: Calendar Recurring/Repeating Events - Best Storage Method
My issue comes from the fact that I would need to add some data for each single event, such as if payments have been made for each single event, confirmation, notes, etc.
This would end in creating a different table with a single row for each event created. In other words, physically adding a row for each event instead of using "recurrent patterns".
I can't see a solution for avoiding 1 line in the DB for 1 event. Any suggestion? In my system, each user would not have many events, let's say a maximum of 50 events per week.
Let's assume you have a table already to store recurrent events, such as
table recurrent_event
id bigint
start date
interval int -- as simple or complex as needed
Now your application will need some logic anyway to calculate which single events will come from this, e.g. to display a list of single events. I would not store a list of all these singles events in the database, as, initially, this list wouldn't add any useful information. Also, the list would have to end somewhere, so it might fail to encompass all single events coming from the recurrent event. The only need to insert a record for a single event arises when some additional information for the event gets actually entered. Just for these single events, I'd create a
table single_event_additional_info
id bigint
recurrent_event_id bigint
single_event_date date
additional-information ... whatever datatype fitting
that points back to the recurring event. So, when treating a recurring event, selecting from this table all single events referring to it will yield all information relevant for the recurring event. The rest of single events will still be determined by calculation.
Related
I am wandering how should I design the database according to this requirements.
I have:
multiple users with calendars
multiple events for one date
one event can be assign to many dates
to each event is assign only one person (different than user this event belongs)
I would like to easily have access to all events for a particular date for specific user and also have access to get all dates for the specific event for the same user. Would be also perfect if I could get all events for which a given person is assigned.
I was thinking of creating Date table and Event table with userId and Dates columns and store all datesId for specific event but it won't be easy to get all user events for certain date and person.
Second idea was to create Date table and keep all information in one column for specific date in JSON format, something like:
user1:{event1, person1, event2, person2}, user2:{event3, person3, event4, person4}
But in this approach there will be difficult to get all dates for certain event and also for person.
Another idea was to create different calendar table for each user but this seems to be very inefficient and I guess problematic when adding new users.
Is there any good approach to achieve my goal?
We are building a warehouse stock management system and have a stock movements table that records stock into, through and out of the system, for each product and each location it is stored. i.e.
10 units of Product A is received into Location A
10 units Product A are moved to Location B and removed from Location A.
1 unit is removed (sold) from Location B
... and so on.
This means that over to work out how much of each product is stored in each location we would;
"SELECT SUM('qty') FROM stock_movements GROUP BY location, product"
(we actually use Eloquent but I have used SQL for an example)
Over time, this will mean our stock movements table will grow to millions of rows and I am wondering the way to best manage this. The options I can think of:
Sum the rows as grouped above and accept it may get slow over time. Im not sure how many rows it will take before it actually starts to cause any performance issues. When requesting a whole inventory log via our API each row would have to be summed for every product, so this will compile to a fairly large calculation.
Create a snapshot of the summed rows every day/week/month etc. on a cron and then just add the sum of the most recent rows on the fly.
Create a separate table with a live stock level which is added to and subtracted with every stock movement. The stock movements table shows an entire history of all movements while the new table just shows the live amounts. We would use database transactions here to ensure they keep in sync.
Is there a defined and best practice way to handle this kind of thing already? Would love to hear your thoughts!
The good news is that your system is already where a lot of people say the database world should be moving: event sourcing. ES just stores every event against an object, in this case your location, and in order to get the current state you have to start with an empty object and replay all of that objects events.
Of course, this can be time-consuming, and your last two bullet points are the standard ways of dealing with it. First, you can create regular snapshots with the current-as-of-then totals for that location, and then when someone asks for the current-as-of-now totals you only need to replay events since the last snapshot. Second, you can have a separate table of current values, and whenever you insert a record into your event store you also update the current value. If they ever get out-of-sync, you can always start fresh and replay the entire event series again.
Both of these scenarios are typically managed through an intermediary queue service, like SQL's Service Broker, RabbitMQ, or Amazon's SQS: instead of inserting an event directly into your event store, you send the change into a queue and the code that processes the queue will update your snapshot.
Good luck!
I want to initiate an action after 7 days from the day a specific field in my database table is updated.
I can use trigger to trigger an event on update of field in the database table. But how can I make it wait for 7 days. I was looking for scheduling an Event but that can only be scheduled for specific time. Is there any way to dynamically set the schedule time?
There are 2 ways to do it:
You store in a timestamp field when the record was last updated. You schedule a regular event to be run every couple of hours. The event's code scans the table in question and does whatever needs to be done for those records those timestamp is between the lust run of the even and the current time.
If you have lots of records you need to handle such events, then this is the recommended approach. The drawback is that timing of the event may not be fully accurate, depending on how often you schedule this event to run.
Every time you update the record you create an event specifically for that record in a trigger or stored procedure that triggers in 7 days time.
This approach gives you absolute accuracy over when an event is triggered, however, if you have a large number of changes, then this solution does not scale well.
An alternative solution could be to record the time when the change was done, but instead of event triggering base your code on user interaction. So, if the user, whose data has been updated logs on then you notify him about what you want regarding those updates that were done more than 7 days ago and the events were not seen by the user.
We're trying to create a template date prompt to be used across multiple universes, and also be used against multiple date fields (for instance, Transaction Date, Invoice Date, etc)
The prompt should display a list of values like the below (there's about 30 total):
Date Range START_DATE END_DATE
-------------------- ------------------------------ --------------
D: Yesterday 12/02/2015 12/03/2015
M: Month Before Last 10/01/2015 10/31/2015
M: Month to Date 12/01/2015 12/02/2015
Our initial attempt at this (creating a derived table, and then some aliases against the derived table, with one alias for each date type such as Transaction Date, Invoice Date, etc) was a failure - the sql generated is wrong, and includes the sql that's just supposed to provide the list of values. I think we need to use a different approach entirely.
Thanks for reading so far. I would greatly appreciate any ideas! Feel free to ask questions and I'll edit my notes to answer.
EDIT - we're using UNV (legacy Universe Design tool)
I'm going to assume you have an existing (dimension) table that contains a record for each date and the necessary columns to hold the different representations. You can also create a derived table for this.
Here are the steps to achieve what you described (sorry, no screenshots, this is off the top of my head):
Create the required dimension objects (based on your date table) in a separate class in the universe (you can hide this class at the end; the end user shouldn't see them).
Take one of the date dimension objects (e.g. Transaction Date, Invoice Date. …), enable the LOV option and edit it (which should bring up the query panel).
In the query panel, select all the dimension objects, created in step 1, that you want to show in your LOV. Important: the object holding the value to be returned, should be placed first in the query panel. Run the query (nothing will appear though).
Make sure that you enable the option to Export the LOV, otherwise your customisations will be lost upon exporting the universe. Optionally, enable the option to refresh the LOV each time the user calls it.
As you can't really define a single, reusable LOV in UDT that you can reference in different dimension objects, you'll have to perform this for each dimension object that you would want to have this LOV.
One way around this annoyance may to define the customised LOV once, note down the generated LOV name (about 8 alphanumeric characters long) and then replace the LOV name in the other dimensions with that LOV name. I'm can't guarantee that this will work though.
In contrast: with IDT you can define a customised LOV like this once (either in the Data Foundation Layer or the Business Layer), and then reference it as much as you want.
I'd like to keep track of the operations of an application that uses a mysql database mostly read-only. I know that there are a lot better ways to keep track of operational metrics, but as a quick and dirty start would it be horrible to have table with date and hour_of_the_day columns and then a count column to keep track of the occurrences of some event during that hour?
There would be a lot of contention on only a few rows, right? Is this preferable to created in an entire new row per event?
If you're going to go this route, which I don't think is a bad idea, you might want to create a new row per event. You can have columns such as event type (an ID), datetime of event, etc. You could then count the events by doing a count() query on a certain event type.
Then you can link it to an EventType table to where you specify what each event type is, such as name of event, description, etc