In a table for a users billing subscription info, there is the need for a field that states how often they are billed. Currently the only options are monthly or annually.
What is best practice in this case? Keep the actual value in a field of the subscription table or create a subscription frequency table, have annually be 1, and monthly be 2, and insert the ID into the subscriptions table?
With the specification, as given, with no other information...
My personal preference would be to just store the "subscription frequency" attribute in the entity table.
No need to create a separate table. (I don't see "subscription frequency" as being an entity in the system, and I've already got enough complexity with referential integrity and foreign keys for stuff I really need it for.)
I don't every query against my table to require a join to the "lookup" table to return a string value, out of an id. That just seems unnecessary.
Personally, I'd consider adding a column like this:
subscription_frequency ENUM('','monthly','annually')
If I need to add another value to the list:
ALTER TABLE mytable
MODIFY subscription_frequency ENUM('','monthly','annually','quarterly')
The ENUM examples here require only a single byte of storage. And the INSERT/UPDATE/SELECT statements with the ENUM work as if it was a VARCHAR, with some funkiness with INSERT/UPDATE of string values that aren't in the enum list.
If there's reasons to avoid ENUM, then I would just store the VARCHAR.
If I needed the extra lookup table, I wouldn't use a surrogate id as the primary key. I would use the string value 'monthly', 'annually' as the primary key, and the foreign key column. (I want to avoid requiring a JOIN to return a string from an id.) If there's an order to the values in the list, I'd add a sequence column to order them.
The billing-frequency is just an attribute of the subscription. And there is only one such attribute per subscription. So in my opinion there is no need for an extra table and join.
You could, of course, add an extra table with possible billing frequencies. Like 1: annually, 2: monthly, 3: weekly or whatever. And using that id as value in the billing-frequency-field of your subscription table.
Alternatively, you could store the amount of billing processes per year in that field and make the "naming" in your application. (1 = annually, 12 = monthly, 52 = weekly and so on).
This comes down to preference and expand-ability. I would personally create another table called something like SubscriptionFrequency with attributes id,description,billingFrequency,createDate,lastModifiedBy,etc... or something to that effect. The value you store in your UserBillingSubscriptionInfo could be a foreign key to this new table's primary key. If you do the other option (simply imply 1 = annual and 2 = monthly) I'd add descriptions to the schema or document somewhere how that relation works.
Related
Updating the array without updating the existing record in it.
I am having a users table and course table. In course table i have
user_id and i want this user_id column data to be in array. So i
could define that this course has been taken by how many users.
I had Already tried it bu using insert method but it's not working and here the problem is we have update as well as create. So i am confused about how to get rid out of it.
For this how to update the array without updating existing id's in
array.
Thanks in Advance!!
and i want this user_id column data to be in array
Don't do that. You'll only be making things more difficult for yourself. The problem you're currently experiencing and asking about is just the tip of the iceberg.
Instead, create another table which has a foreign key to the users and a foreign key to the courses. Maybe call it something like usercourses:
usercourses
--------------------
id | INT PK AUTOINCREMENT
user_id | INT FK
course_id | INT FK
Conceptually, each record in that table represents an association between a users and a course. Each association is trackable and editable independently. This is called a "many to many relationship" between users and course.
As the complexity of the data grows, in cases like this the association itself can easily become its own entity. For example, in the domain of Students and Courses consider an entity called a Registration. It is the association between a Student and a Course, but also carries its own business data. The dates of registration, the student's grade perhaps, etc. Storing all of this in your array and stuffing it into a single string field would be problematic to say the least.
I just would like to know what are the most common approaches to get a table to hold a reference to IDs from multiple tables.
I have a system with modules like customers, suppliers, orders, etc. and I would like to add a "Notes" functionality to all of those modules to be able to add/read notes.
As one customer/supplier/order can have multiple notes, I have chosen the one-to-many relation way and so the notes in their table should refer to the particular item id in a separate column.
But as I will refer to IDs from multiple tables, their IDs will be overlapping and I need a way to say in which particular table to search for that ID.
I don't want to create exact the same notes module for each of my modules and here I could concentrate notes in one table. Those notes differ only in the fact, to which module they belong to.
Shall I
store the particular table name in the notes table? But that name can
change later and the system will break
introduce something like UNIQUE ID or a hash to all of my modules,
which would be unique among different tables and store it's id in
the notes table?
create separate notes table for every module and don't worry about
code/class/table duplication?
Thanks for your ideas!
We do something similar with notes that can be attached to many objects. Each of our objects has a unique class id (we store each type of object in it's own table), and we store the unique class id + specific object id in the notes table.
We then just have to maintain a lookup of unique class id -> table name. By using the unique class id + object id as the key we ensure that the same id in different tables isn't an issue.
I have a table named orders_products which hold all the products associated with each individual orders. Now, if the customer decides to edit the quantity, the attributes, or simply just remove a product, what would be the easiest way to handle this change in the database?
orders_products
id | quantity | fk_products_id | attributes | price | fk_orders_nr
fk_products_id refers to the actual product id in our products table
attributes is a comma sepparated string with id's refering to our attributes table (attributes can be the angle, lenght, diameter etc. for each product. As in 45 degres, left angeled, 20 cm in length, 43mm in diameter).
fk_orders_nr is the actual order the product belongs to.
Since I have a class that handles this part on the client side. Would it be easier to just DELETE all associated products, based on the order id (fk_orders_nr), and just re-insert and updated the whole set based on what's stored in the class?
Or is there a neat way to handle this directly in MySQL?
I've looked a bit into on duplicate key update, and ignore, but they doesn't seem to fit my needs..
I need to check to see if the actual product id exists, then decide to insert new, or update existing (it could be both the quantity, and/or optional attributes), also the product might be removed if not in the list from the class anymore.
When writing this question. I think deleting the whole set, and reinsert it, might be the easiest way.
This database looks badly designed. Firstly I assume by fk_products_id you mean product_id. You do not need to specify that a column is a foreign key in its name.
Secondly, I would advise you to keep all columns atomic, as in, no multi-values. The attributes column keeping a comma-separated list will give you headaches in the future and it also breaks the FIRST normal form (the most basic one).
Thirdly, you don't need (although it could sometimes be useful) an id as a primary key in your junction table. You can just use a compound primary key from your fk_products_id and fk_orders_nr keys.
When writing this question. I think deleting the whole set, and
reinsert it, might be the easiest way.
Yes, that is the way it's usually done.
But I insist you ignore everything about the current problem you're having and redesign your database from scratch, putting special attention into normalization. These are basic database design standards and they exist for a reason. Hopefully you won't learn about the reason when it's too late.
I'm very new to PHP. I'm building a companion webservice for an iPhone application I'm creating.
I have the following DB table that i've created which is filled with triggers.
The basic concept is that for a given currency when the price hits the trigger price I'm going to send a push notification.
Before I can generate the push notification I need an elegant way to validate each entry in this table against the current market price.
On initial thought I was thinking to select each trigger price and each currency and compare against the current market price I have in another variable.
Could anyone tell me the most elegant way to achieve what I'm trying to do? (compare the whole table against market price for various currencies)
Also if you have any php snippets that would be great,
Thanks,
John
Well if the app has a user logged in then you only need to check for the rows for that user, which isn't that bad.
However I would implement the database differently, have a separate currencies table like this:
id SERIAL
currency_name VARCHAR(10)
market_price FLOAT
Then change your main table so that target_price is a FLOAT as well (you could use int if you store the number of cents -- or equivalent -- instead of a dollar value, so 103 instead of 1.03). Finally change currency to be an int that references the other table
currency_id INTEGER
Then you probably want to add a foreign key constraint to the table:
FOREIGN KEY (currency_id)
REFERENCES currencies(id)
Now you can update the currencies table as the market_price changes then use SQL to get a list of the rows that need triggered:
SELECT u.id
FROM users u, currencies c
WHERE u.currency_id = c.id
AND u.trigger_price <= c.market_price
;
That's probably the best way, in my opinion.
If you really need to do it in PHP then I'd create an associative array of the market prices where prices['currency_name'] = market price for that currency. And currency name matches the string in the table. Then you're just going to have to go through the whole table and check each match, assuming you've already fetched the table into $result and checked for errors:
while ($row = $result->fetch_assoc()) {
if (isset($prices[$row->currency) // Sanity check on the prices array
&& ($row->trigger_price <= $prices[$row->currency]))
{
// Matching row, do something with it ...
}
}
If you trust the database to only contain stuff in the currency array you can skip the sanity check. If you only want to check certain currencies you could only select rows that match currencies you have updates for.
I'm also assuming your condition is the trigger price being lower than the current price, you may need to do different logic depending on exactly what you want to do.
For example, let say a user purchase product called soap with price of 1.50 on 20th sept 2012. This have been recorded on database under purchase table with productID and date.
Let say on 22nd sept 2012, the admin changed the price of soap to 1.20, now the report price is changed because of this.
What is the best approach to make sure that old data of 1.50 is stored for old reports and 1.20 for new reports. Should i insert all data including, product name, product price onto purchase table?
The simple answer to your questions is yes.
When it comes to financial systems, well any systems that may be required to be audited "transactions" should be stored in their entirety in a "document" or "record".
There are other methods such as recording each deletion or modification with "flags" (E.G. current, deleted, modified, etc), "from_date" and "to_date" instead of actually deleting or modifying the data from the database, however this will use more server resources and the programming is significantly more complicated not only in mySQL but PHP also. But it allows you to provide only a relationship between records at the same time.
My suggestion is to keep it simple and store all required data in a single record. You will save time and legally, should the system ever need to be audited you're much safer.
Good luck and I hope it helps!
I don't think it is necessarry to store the product name in the purchase table, but the product price I think that should be stored.
Also if you don't store the product name in the purchase table you should take care about deleting products. Maybe deleting them is not the best idea so you should hide them from the store but not deleting them from db.
I normally store the price for the product on the purchase table with the productID and date, or if you can have multiple items in the cart, you will have a purchase table and a purchase_product table. This was if you ever add coupon codes or anything else like that you will always be able to see what the person paid for the item on that particular purchase.
I've recently been working on a product close to what you described. And I believe your answer relies on the level of complication you are willing to implement your project. The simplest way is to store product information in your invoice record. But this leads to redundancy over the time.
On the other hand you can implement a revision mechanism so you can keep track of your records' changes over the time. This can be easily done by using two ids for your records instead of one. Here's a sample table:
CREATE TABLE IF NOT EXISTS `product` (
`product_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`entity_id` bigint(20) unsigned NOT NULL,
`name` varchar(255) NOT NULL,
`price` double NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`),
KEY `inx_entity_id` (`entity_id`)
) DEFAULT CHARSET=utf8 ;
While product_id is your ordinary auto increment id, the entity_id is a special id which is the same for all the records of the same product. In this design you'll never delete a record, nor update it. You will always just insert into the table and when you need to get the list of products, you'll just have to keep in mind that a group by over the entity_id is in order. The product information can be found in the record with the biggest product_id. Perhaps you may want to create an entity table to keep track of entity_ids.
This design is more complicated than copying products' information to invoice. But it has so many great benefits. Like you can keep track of price changes of a product. Or you can use a foreign key to product_id to point to one specific revision of the product or use the entity_id to indicate a product type instead of some specific revision of it. Of course its complication will cost you but it's you who can tell if it is worth it.