Table structure doesn't allow for needed functionality - php

CURRENT FUNCTIONALITY:
In my financial/budgeting app, the current functionality allows a user to add a recurring budget category that will appear in each month's budget. It does this by allowing a user to select a "recurring" option from a dropdown, which makes 2 additional dropdowns appear, one with a beginning month and one with an ending month. When the category is recurring, it writes the beginning month and the ending month to the database (diagram below).
DESIRED FUNCTIONALITY:
The problem with the current design is that I want the user to be able to delete one (or more) month from the recurring months. So lets say I set up a recurring category in January for the entire year. Then I get to May and I want that category not to appear for that month. If I delete the category, it currently deletes it for all months, past and present. I need it to have the option to only delete only the desired month(s).
I'm not sure how to accomplish this, and I thought maybe someone has a good idea. Maybe my database structure is off? In the interest of normalization, I didn't want to just add a column for each month or anything like that.

Rather than storing the recurrence formula, IMHO it would be best to store the actual months in a many-to-many relationship:
categories
----------
id
name
months
------
id
category_months
---------------
cat_id
month_id
When a user enters a recurrence formula, it will create the relationships. Then they will be freely able to remove months one at a time if necessary.

Related

Simple membership database design approach [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm a bit unsure what is best way to tackle one requirement that I have on my project (Laravel API and Angular UI). So I have one pretty straightforward task. I need to create database schema for members and their subscription status for months in selected year.
I need to keep this as simple as possible, because this is a very simple admin app, where admin user will manually mark paid status for each member when they pay, so there is nothing special or advanced here. On UI it should look like this:
So basically every year members can pay membership for every month in that year.
Note: x means member payed membership for that month.
From database standpoint I'm thinking and trying to decide about something like this:
Note: membership and another_membership are tables that I'm consider to use, I will chose one of them, based on suggestions
So basically the idea behind this is pretty simple, every time member pays, membership table will be updated with date and member id, and that way I will have all payments for every member.
Because of UI from first picture I have few problems that I'm not really sure how to approach.
In order to generate bootstrap table from first image I'm thinking something like, for example if I want to get all memberships for year 2018 from certain selection I will do something like:
Select * from member m left join membership ms on m.id = ms.member_id where date >= 01-01-2018 and date <= 01-31-2018 and m.selection_id = 1
But I'm still unsure what is best way to map members each month status. I'm thinking maybe to group all dates from membership table and then somehow to generate this table
Anyone have any suggestions on this? Should I use membership table or another_membership table? Should I do mapping (members and months statuses) on UI or API side? Any other suggestion? Someone told me that it might be a "good" idea to create simple table with member_id, year, and all 12 months as attributes and just store true/false for each month there. Something like this:
Also one thing that bothers me, is it good idea maybe to first get all members, and then get all data from membership table based on member ids, so for example if I have pagination of 20 members I will make db call like this:
Get page 0 with 20 members
select * from membership m where m.member_id in (list_of_ids)
You do not want to store membership information in columns. Either membership or another_membership are fine -- they store the values in rows.
Which to choose? That is really up to you. For a general application, I would go for something like:
MemberShipId
EffDate -- from date
EndDate -- to date
PaymentDate
. . . other information
You are set on the memberships being for one month periods, so having either a single date (say the first of the month) or splitting out the columns into (year and month) are fine.
What #GordonLinoff writes is how I would structure the database.
The next thing you probably need is a way of pivoting your rows to columns; you probably end up with a query that produces output along the lines of:
UserName Month Member
---------------------
Tom Jan18 null
Tom Feb18 1
.....
This question shows you how to convert that into the rows your front-end cares about.

MySql: saving date ranges VS saving single day

I am currently working on a simple booking system and I need to select some ranges and save them to a mysql database.
The problem I am facing is deciding if it's better to save a range, or to save each day separately.
There will be around 500 properties, and each will have from 2 to 5 months booked.
So the client will insert his property and will chose some dates that will be unavailable. The same will happen when someone books a property.
I was thinking of having a separate table for unavailable dates only, so if a property is booked from 10 may to 20 may, instead of having one record (2016-06-10 => 2016-06-20) I will have 10 records, one for each booked day.
I think this is easier to work with when searching between dates, but I am not sure.
Will the performance be noticeable worse ?
Should I save the ranges or single days ?
Thank you
I would advise that all "events" go into one table and they all have a start and end datetime. Use of indexes on these fields is of course recommended.
The reasons are that when you are looking for bookings and available events - you are not selecting from two different tables (or joining them). And storing a full range is much better for the code as you can easily perform the checks within a SQL query and all php code to handle events works as standard for both. If you only store one event type differently to another you'll find loads of "if's" in your code and find it harder to write the SQL.
I run many booking systems at present and have made mistakes in this area before so I know this is good advice - and also a good question.
This is too much for a comment,So I will leave this as an answer
So the table's primary key would be the property_id and the Date of a particular month.
I don't recommend it.Because think of a scenario when u going to apply this logic to 5 or 10 years system,the performance will be worse.You will get approximately 30*12*1= 360 raws for 1 year.Implement a logic to calculate the duration of a booking and add it to table against the user.

How to check for blocks of availability in a MySQL booking database?

I have an accommodation booking engine, which follows these rules:
Users can book up to 7 rooms for any date.
Users must book only blocks of 2 days, 4 days and 6 days.
Users cannot book for Thursday (closed for cleaning).
Sometimes entire weeks will be unavailable due to corporate group bookings.
Here are some examples:
A 2 day block might be Friday and Saturday, Sunday and Monday or Tuesday and Wednesday.
A 4 day block might be Friday to Monday or Sunday to Wednesday.
A 6 day block might be from Friday to Wednesday.
The system has a simple table in the database that is a list of each date with the 7 rooms. The field for each room can be 0 for unavailable or 1 for available.
Table is called vg_booking_availability. Here is a snapshot.
I need a way to search the table against a users search selection.
The might search as any combination of 2, 4 or days and between 1 and 7 rooms.
I'm not sure if the solution is to do a database lookup on all dates and all rooms, then creating a multi-dimensional array and cross checking with the user's search is the way to go forward. And if it is how I would do this?
Here is a way to do this in SQL, for just two-day bookings, for room_1:
SELECT
avail1.date start_date,
"room_1" room_name
FROM vg_booking_availability avail1
/* This row is the next day to the first one */
INNER JOIN vg_booking_availability avail2 ON (avail1.date + 1 = avail2.date)
WHERE
avail1.room_1 = 0
AND avail2.room_1 = 0
/* Add in a clause to check future dates only here */
;
You could add all the rooms in this as bracketed OR statements, but I'd be inclined to run that as a separate query (otherwise you'd have to re-search your result in PHP to determine which room returned as available)
We are getting into a bit of trouble here because all the rooms are denormalised - they would be better in another table where they can be treated much more generically.
This example can be expanded by adding more aliased rows for 4-day and 7-day searches respectively. The unavailability of rooms on a Thursday (or whatever other rules) is not directly relevant to the problem, since you can just create future rows of availability (based on how far into the future people book) and then make rooms unavailable according to those rules. That's a separate (and trivial) problem.
I'd also be inclined to change this, so you use NULL as available and a foreign key to a customer table as unavailable. That will then give you useful information about why a room is unavailable, and will allow you to make it available again easily if a specific customer cancels their booking.
Lastly, this solution has the capacity for a large number of joins, and so testing this against data sets is essential. If you were to run this on a 10K row table it'd be fine, but it might not be if you have 1M rows (depending on your hardware and load, of course). So, once you have this working, I recommend you create a data generator (PHP is good for this) and ensure you can get the performance you require.

Dynamically add group of fields in magento while creating products

I am creating a tour portal in magento 1.8.
The thing I need is to add a group of fields included in the itinerary like place of departure and time according to the no. of days specified for the tour.
eg. If i specify the tour duration to be 2 days i should get 2 sets of the above fields grouped as day 1 and day 2.
How can i accomplish that?
i dont think Magento provide any feature as desired by you, you either need to create custom module where you can provide a list of all products and then add/edit/delete the groups on day basis.
Another approach to start can be using different attribute sets for different days tour, and then add no of attributes needed in each attribute set.
Hope this will help in starting the development.

achievement system for consecutive actions

I'm about to create a new competition site, where users can upload pictures/vote.
I want to add some achievement bonuses/badges based on some very easy "achievements".
Achievement examples:
Login for 5 consecutive days --
Login for 10 consecutive days --
Login for 20 consecutive days
Vote 5 pictures (not yours) --
Vote 5 pictures for 5 consecutive days
I want to be able to add more achievements without adding too much code later on. A basic rule engine will be created.
Now.. I am having some troubles trying to think out how to do it. Anyone did something similar and wants to share database structure/coding examples, or someone with a good idea for this?
Read about 50 different threads on the topic here on SO, but couldn't find anything usable.
Make a new field in the table that will contain the date of the last activity (probably name it like lastactivity), and then create another one and name it something like consecutive. After that, each time the user login (or vote), check the last activity date and if it's yesterday, increment the value of the field consecutive by one and update the lastactivity field. Otherwise, reset it to 1.

Categories