Below is the current design of school fees and payment I have created.
I'm just a little stuck right now because I can't model the payment/transaction table. Also, I would like to know your thoughts and comments with my current design. This is the first time I'll create a database for fees and payments.
Main tables of my concern are schoolyearfee_lt , student_fee_lt and Payment
I'm thinking of using the Payment table to store the sum of all fees on which will be divided to whatever payment term was chosen (monthly,quarterly,annual,cash).
Let's say for instance, Monthly was chosen as payment plan.
amountToPayPerMonth = (sumOfAllAssignedFees / paymentterm) - downpayment
Where 11 inserts of the amountToPayPerMonth to payment table will be executed and 1 downpayment. 11+1 = 12 months
How do I mark it as paid? Should I use another Transaction table?
Is this a good design? Any thoughts or advice?
Thank you.
some (personal) thoughts about your design and question.
1- schoolyearfee_lt. It seems 1-to-n with fee_mt. If i well understand the same fee can be applied for several shoolyears, category etc, but the amount for a fee does not change. It means, for example, that every year in which fee amounts change i should create -at least- a new fee and some shoolyearfee. I believe something can be reviewed here. I could from example move some of its fields (schoolyear?) to the fee_mt table, and/or i could move the amount from fee_mt to schoolyearfee_lt. There are also some more possibilities, i.e. making a table fee_years_lt, where storing year and amount (and maybe other factors which change the fees) and so on. Maybe you could make some of these changes, maybe none, depends on your design and requirements. The questions may be: is the amount changing by year (i believe yes), gradelevel, feetype, feecategory or not ? You want a master fee that you want applicable forever or your fees are recreated each year from scratch ?
2- Payment. I would call it exactly with its meaning: payment_plan. I would add a field paid, a field payment_date and a field schoolyear (in current design).
3- Student_fee_lt and schoolyear. In the current design you better add the year too. Depending on the mode the fee_mt is managed (see above) i would put it in the PK too. Moving the year to the fee_mt, you don't need. Is student_fee_lt really needed (it seems the result of a query + the field date_effective) ?
4- Payment Formula. The downpayment and consequently the formula is a little nclear to me. Is it a kind of discount for every payment you do or is it a fixed amount ? In the latter you should review your formula. Why 11 payments ?
5- Choosen Payment Plan storage. I would have a table where storing the chosen payment plan by the student (and some other data), this should not be student_fee_lt, because it stores the single fees assigned for each student.
Related
I'm writing a simple transactional database to practice my T-SQL skills.
If I sell an umbrella in my sales.orderdetails table and it's getting the current retailprice of that umbrella from the items table and putting it in the invoice, how do I keep from having incorrect historical report data 6 months from now when I jack up the retail price of the umbrella by $10?
How do i store that umbrella sold price in the orderdetails table so it's unaffected by any changes in the items table in the future?
I know you can use an SCD for a datawarehouse for this kind of issue but was wondering how to do it in an OLTP system. Computed persisted column? Can't seem to get that to work in the object explorer when I try to enter the items.retailprice as the computed value for the salesorderdetails.cost column.
The way I have seen this done in the past, without using a technique like SCD, was to have the order detail have the price that was charged and then use a foreign key to another table, possibly products or productprices, that contains the current price.
In a full-on transactional system, you'd want the order detail row to record full retail (MSRP, or what have you), current price (in case you had the item posted at a discount that day), and price charged (in case the customer used a promo/coupon code to reduce the price themselves). Unless you log all three, you're at the mercy of whatever the price changes to tomorrow or next week or next year, which makes for bad analytics.
You probably also want to capture current cost of goods, too, since that's subject to change over time, especially in an average costing scenario. Otherwise, margin calculations will be suspect.
But then, yes, a foreign key or keys to any other descriptive tables for those less ephemeral characteristics of the product.
I am currently working on a web application that stores information of Cooks in the user table. We have a functionality to search the cooks from our web application. If a cook is not available on May 3, 2016, we want to show the Not-Bookable or Not-Available message for that cook if user performs the search for May 3, 2016. The solution we have come up to is to create a table named CooksAvailability with following fields
ID, //Primary key, auto increment
IDCook, //foreign key to user's table
Date, //date he is available on
AvailableForBreakFast, //bool field
AvailableForLunch, //bool field
AvailableForDinner, //book field
BreakFastCookingPrice, //decimal nullable
LunchCookingPrice, //decimal nullable
DinnerCookingPrice //decimal nullable
With this schema, we are able to tell if the user is available for a specific date or not. But the problem with this approach is that it requires a lot of db space i.e if a cook is available for 280 days/year, there has to be 280 rows to reflect just one cook's availability.
This is too much space given the fact that we may have potentially thousands of cooks registered with our application. As you can see the CookingPrice fields for breakfast, lunch and dinner. it means a cook can charge different cooking rates for cooking on different dates and times.
Currently, we are looking for a smart solution that fulfils our requirements and consumes less space than our solution does.
You are storing a record for each day and the main mistake, which led you to this redundant design was that you did not separate the concepts enough.
I do not know whether a cook has an expected rate for a given meal, that is, a price one can assume in general if one has no additional information. If that is the case, then you can store these default prices in the table where you store the cooks.
Let's store the availability and the specific prices in different tables. If the availability does not have to store the prices, then you can store availability intervals. In the other table, where you store the prices, you need to store only the prices which deviate from the expected price. So, you will have defined availability intervals in a table, specific prices when the price differs from the expected one in the oter and default meal price values in the cook table, so, if there is no special price, the default price will be used.
To answer your question I should know more about the structure of the information.
For example if most cooks are available in a certain period, it could be helpful to organize your availability table with
avail_from_date - avail_to_date, instead of a row for each day.
this would reduce the amount of rows.
The different prices for breakfast, lunch and dinner could be stored better in the cooks table, if the prices are not different each day. Same is for the a availability for breakfast, lunch and dinner if this is not different each day.
But if your information structure makes it necessary to keep a record for every cook every day this would be 365 * 280 = 102,200 records for a year, this is not very much for a sql db in my eyes. If you put the indexes at the right place this will have a good performance.
There are a few questions that would help with the overall answer.
How often does availability change?
How often does price change?
Are there general patterns, e.g. cook X is available for breakfast and lunch, Monday - Wednesday each week?
Is there a normal availability / price over a certain period of time,
but with short-term overrides / differences?
If availability and price change at different speeds, I would suggest you model them separately. That way you only need to show what has changed, rather than duplicating data that is constant.
Beyond that, there's a space / complexity trade-off to make.
At one extreme, you could have a hierarchy of configurations that override each other. So, for cook X there's set A that says they can do breakfast Monday - Wednesday between dates 1 and 2. Then also for cook X there's set B that says they can do lunch on Thursday between dates 3 and 4. Assuming that dates go 1 -> 3 -> 4 -> 2, you can define whether set B overrides set A or adds to it. This is the most concise, but has quite a lot of business logic to work through to interpret it.
At the other extreme, you just say for cook X between date 1 and 2 this thing is true (an availability for a service, a price). You find all things that are true for a given date, possibly bringing in several separate records e.g. a lunch availability for Monday, a lunch price for Monday etc.
I has a structural performance question.
I am preparing a book selling web site. I has books, authors, categories ect. I want to give users some discounts. But these discount can be about book, category, author and even can be about user. I am storing discounts at 'discounts' table and storing types. When people list products, i want to show discounts too. If i join discounts table and product table and check for total discount for each record that is a huge performance issue for listing. Do you have any suggestion for this and something like this situations?
(Note: I can put discount into product table and calculate it daily with a sql job but i has more tables with that problem. Discounts is just a sample and i wanna learn alternative ways for something like these issues.)
Sorry for my bad english, thanks.
If i join discounts table and product table and check for total
discount for each record that is a huge performance issue for listing.
Ah. No. Tried 10 years ago for an online shop we created and we figured out that with some simple caching (shop products, with all elements together) in memory (we could live showing 5 minutes outdated prices in case of a change) plus output cache of the non-super-simple way we could mitigate pretty much all the performance impact.
Make a clear database. Then make a smart architecture on top of it. Not every item must all the time be queried from the database.
I am working on a multiple properties booking system and making me headache about the best practice schema design. Assume the site hosts for example 5000 properties where each of it is maintained by one user. Each property has a booking calendar. My current implementation is a two-table-system with one table for the available dates and the other for the unavailable dates, with a granularity of 1 day each.
property_dates_available (property_id, date);
property_dates_booked (property_id, date);
However, i feel unsure if this is a good solution. In another question i read about a single table solution with both states represented. But i wonder if it is a good idea to mix them up. Also, should the booking calendar be mapped for a full year with all its 365 days per year into the database table or was it better to map only the days a property is available for booking? I think of the dramatically increasing number of rows every year. Also i think of searching the database lately for available properties and am not sure if looking through 5000 * 365 rows might be a bad idea compared to i.e. only 5000 * av. 100 rows.
What would you generally recommend? Is this aspect ignorable? How to best practice implement this?
I don't see why you need a separate table for available dates. If you have a table for booked dates (property_id, date), then you can easily query this table to find out which properties are available for a given date
select properties.property_name
from properties where not exists
(select 1 from property_dates_booked
where properties.property_id = property_dates_booked
and property_dates_booked.date = :date)
:date being a parameter to the query
Only enter actual bookings into the property_dates_booked table (it would be easier to rename the table 'bookings'). If a property is not available for certain dates because of maintenance, then enter a booking for those dates where the customer is 'special' (maybe the 'customer' has a negative id).
I have to store a list of history pricing data history. I use the histroy data to look over the last 28 days. I pick the highest value from the last 28 days and then compare that with the current value where the difference is the sale discount.
Our DBA says store the data in a table that has a FROM DATE and a TO DATE were a TO DATE of NULL will be the current price. However for performance reasons he also wants to store the current price in the stock items table. There will be triggers to ensures the stock item price matches the lastest price in the price history data. I don't envisage a stock item having more than 10 price changes
I can't help thinking having the current price in two location is a bad idea. However, I also do like getting the current stock price from the stock item row. We have an sql 2000 database.
Not sure what's the best approach is.
Either approach is valid. The deciding factor should be the overall performance impact of each solution.
Since looking up the current price probably happens much more often then updating the price, you should choose a solution that maximizes the performance of look ups.
Depending on the overall design that will most likely be the price in the actual stock item row (you are probably already getting that row for other data anyway).
The trigger that updates the price in the other table will only be execute when the price is updated and therefore the performance hit of the trigger will not affect the apps overall performance.
Also, if you are needing to lookup the high price from the past 28 days often, it may be better to have the trigger store that value in your stock item row as well.
This does lead to some data redundany but the performance benefit may well be worth it.
The key to data integrity is making sure that trigger does it's job properly.