Will MySQL allow no primary key if the table is linked with another table containing a MatchID with two Foreign Keys - mysql

I have a database of 5 tables. Some contain the same columns as others, does tying these tables to another table which has the primary keys of other tables meet 3rd normalisation. (This is outlined more clearly below)
I have a table of customers, with their names and phone numbers as well as requirements they want in their car etc. The primary key is CustomerID.
I then match a customer with a car which matches their requirements. I have a table with Match ID (Primary key) and CustomerID and CarID (As foreign keys.)
By doing this, can I then make a table off Match ID which can be given to the receptionist so that they can contact the customer. In this table I would need to include the customer name and phone number. However, does this break 3rd normal form as Phone number is now both in CustomerID and the new table.

The last table you describe doesn't necessarily break any normal form, because the customer's phone number can change in the future. You may want to preserve the phone number in another table so there is a record of what phone number was contacted on that date.
Compare with a database of products. The product table has prices. Then you record customer purchases, with a copy of the price they paid on the date they made the purchase. That's okay because you need a record of what was paid in each case. A customer may buy the product during a sale, or they got a senior discount, or a bulk discount, or the price may change a month after they bought the item, etc. The price they paid is not necessarily the current price recorded in the products table. Therefore it does not violate 3NF.

Related

Is it OK to store redundant data in case records from foreign table are deleted

Let's say I have a database table called products which has a list of products, with the primary key product_id
I then have a database table called purchase_order_products which has a list of products assigned to a purchase order, with a foreign key product_id.
Now, if I enforce referential integrity between the two tables, it only requires a single purchase order to reference a product, and it won't be possible to ever delete that particular product from the database (unless the purchase orders for that product are also deleted).
It seems I have a few options:
1) Enforce referential integrity and don't allow the product to ever be deleted.
2) Don't enforce referential integrity, and if anyone ever views a purchase order where the product no longer exists, simply display the product name as "UNKNOWN" or "DELETED".
3) The final option is to not only store the product name in the products table but also store it in the purchase_order_products table alongside the foreign key. Obviously this is redundant data, but it would allow the product to be deleted from the products table, whilst still allowing users to see the names of now non-existent products that were part of purchase orders in the past.
I'm swaying towards option #3 but wondered what is the "correct" way of handling this.
You can enforce referential integrity and use ON DELETE SET NULL, then display "UNKNOWN" or "DELETED" when a purchase order's product_id is null. Thus, option 1 and 2 aren't mutually exclusive.
Option 3 is valid. Having two copies of product_name isn't redundant if the relations they're used in express different predicates. Product <x>'s current name is <y> is different from When purchase_order <z> was created, product <x>'s name was <y>. It's a common technique to record current and historical prices separately, the same can be done for names or any other attributes of a product.
There is no reason to duplicate data. A simple solution is to implement a soft delete on the products. The best way is to have a date field called something appropriate like Deleted and set it to a date far in the future, like 12/31/9999, for current products. To delete a product, just set the Deleted value to the date the product is deleted. This way, to list currently available products, filter out the products where Deleted is in the past.
When showing purchase orders, ignore the Deleted value so it shows all products, even the ones no longer available. Optionally, you could show by some indicator if a product is one that is no longer available.
You might also want to create a view that ignores deleted products for those times in would not be appropriate to show deleted products, as when creating new purchase orders.
You would also want to write a delete trigger on the products table to convert the delete process to just change the value in the Deleted field. You would also want to have a function in the API to allow a product to be "deleted" as of a certain date. Maybe the product was removed a month ago but the database was not updated. Or the product is slated to be removed at a future date so go ahead and set the date. The product will simply disappear from the current products view when that date is reached.

In access update contact information while retaining record of old in database

In Microsoft Access I have three tables: order table, customer table and product table. My order table pulls in both customer contact and product information. Every now and then I need to update either the customer address. When doing so, I only want the new address to appear on future orders. I don't want Access to update previous orders with an address that was not originally affiliated with that order. I also want to maintain a list of active and past addresses on the customer list. Please advise on the best ways for setting up the customer table and how to retain customer contact information on the order table.
To do this you need to take the customer address out of the Customer table and keep it in a separate CustomerAddress table. This new table has a primary key (of course), a foreign key back to the Customer table, all the address fields that you want to maintain history of and a Current flag (Yes/No). Your Order table then points directly to the CustomerAddress table instead of the Customer table (you can get from Order to Customer because of the FK link on CustomerAddress to Customer). Now your fun starts! You have to maintain your CustomerAddress table in such a way that for each Customer ID you should only have one Address record where Current is True.
The other alternative is to not have a Current flag on the CustomerAddress table, but instead have a CurrentAddress field in your Customer table - this ensures that only one Address can ever be the current one for a Customer. However you can't enforce both the CurrentAddress integrity and the CustomerAddress foreign key - you can't set the value of CurrentAddress until you've added the Address record, so Customer record has to be able to exist with NULL CurrentAddress (although I suppose you could have a dummy 'Not set' CustomerAddress record).
The simple method is to store the current customer information with the order.
The extended method is to store the customer table(s) as temporal tables, either using a custom method or a native as - for example - offered by the newest versions of SQL Server. Look up the term Temporal database for more information.

How do I link a single table to data in two different tables?

I'm running for office and have created a web app for tracking my door knocks to voters at their homes. The database contains a table called voters that contains all the necessary information about voters in my community.
I'd like to add a new feature to track donors to my campaign. Not all of these donors live in the community and do not vote in the district where I'm running for office. I do not need to track the same kind of info for these individuals as I do for the voters so I'm going to place these individuals into a table called nonvoters.
Now, the individuals in my "voters" table can also make donations, and I want to track those as well.
To track the donations from both voters and nonvoters, I'd like to set up a new table called "donations." This table would contain the appropriate details about the donation.
But I'm uncertain as to what the best structure is for linking the donations table to the "voters" and "nonvoters" table. If I create a column called voter_id in the table to key it to the donors information, there's no way to know which table that ID refers to. So do I set up two columns, nonvoter_id and voter_id and insert the ID into the applicable column depending on whether the donor is a voter? This seems weird.
Or maybe I create a column in both the voters and nonvoters table called donor_id that I can use to link my data in the donations table. If I went this route, it seems like I'd have to do a some behind the scenes work to ensure the donor_id was unique and was keyed to the data inside the donations table.
Or maybe there are other approaches I'm not familiar with. Any guidance is appreciated.
I would use a single table for voters and non-voters, let's say persons. You can have a flag in the persons table that indicates if the person is a voter or you may even derive this from their address (if that's possible).
I would create a donations table and link each donation to a person (or persons) in the persons table using the id in the persons table. If a donation can be given by multiple people, then you will need a 3rd connection table with person id and donation id as 2 fields. These 2 fields would be the primary key for the connection table.

Should i stock "quotation_request" as a table on my DB?

I'm working on a very simple DB.
Imagine I've table customer and table seller.
The customer is able to request a quotation for some products
There will be a simple form that allow to customers to select products and submit the quotation.
Now, should I create table : "Quotation" and store all quotations (with id_quotation..etc)?
Thank you all
Without knowing all of the business rules that govern the requirements of this database, perhaps the following design will help to answer your question and explain a few concepts in the process.
In database terms, an entity is a person, place, or thing about which we want to collect and store data. From your description we can already see two entities: seller and customer. This is important since the entities we identify conceptually become database tables in their own right.
The seller table should contain data applicable only to sellers. Thus, the qualities (attributes) about sellers that we want to store become columns in our seller table. Each row (record) in the seller table represents an individual seller. Each individual seller is uniquely identified in the seller table with a unique value stored in it's primary key column, which we can name seller_id.
A simplified version of such a table could look like this:
In a similar manner, the customer table should contain data only applicable to customers. The qualities (attributes) about customers that we wish to store become the columns in the customer table. Each row (record) in the customer table represents an individual customer. Each individual customer is uniquely identified in that table with a unique value in it's primary key column, which we can declare as customer_id.
A simplified version of this table:
I'm guessing the business rules state that any customer is able to request any number of products, from any seller, any number of times...since surely any seller would want as many sales and customers as possible!
How can we express and record the interactions (relationship) between seller and customer?
This is done with a new kind of entity: a composite entity. It becomes a new table, having it's own primary key, and contains seller_id and customer_id as foreign keys. The foreign keys in this table connect (relate) the seller table to the customer table.
We can name this new table quotation (if that is your preferred name). Each row of this table is intended to capture and record each and every individual transaction between a customer and a seller. The columns (attributes) of this table are the data that apply to a transaction between a customer and seller, such as amount or date of sale.
A very simplified version of this composite entity:
Note that the foreign key values that exist in this table must already exist in their respective tables as a primary key value. That is, a foreign key value cannot be entered into this table unless it exists already as a primary key value in it's own table. This is important, and it is called referential integrity - it ensures that there is no record of a customer purchasing from a non-existent seller, etc.
In the example above we can see that Builder B requested a quotation from Acme Construction in the amount of $3500.00. They then requested another quotation at another time for the amount of $1800.00. What else does it reveal? All existing customers have ordered something. Acme Lumber has not made a sale at all (yet), etc.
A design such as this enables the database to store any number of transactions between sellers and customers. Likewise, it supports the addition of any number of new customers and sellers, even if they have not sold or purchased anything yet. Queries can be run that reveal which sellers have sold the most or least, and so on.
Good luck with your studies!

Table with Non Identifying Keys

My company was using this model to manage the inventory
Model 1 http://img534.imageshack.us/img534/6024/modeltest2.jpg
But i was having problems because in this month we bought some plastic bags with a different price, expiration date on the same warehouse.
So now i changed the model to this.
Model 1 http://img16.imageshack.us/img16/8416/modeltest.jpg
My question is if this is ok.. it is working but is the first time i create a table with only no Primary key.
Example of Data:
PRODUCT WAREHOUSE Quantity Price Expiration_Date
PLASTIC BAG NEW YORK 20 1.20$ 12-10-2013
PLASTIC BAG NEW YORK 130 1.50$ 21-12-2015
Thanks
Basically it's OK. In Sales, Warehouse systems you can't save all products with different expiration date in Product Table, because there would be a lot records for each product. But usually you need to save them in "Item_Ledger_Entry" Table where would be all Transactions of Sales or Purcahse.
You using one same Product just with different expiration Date. I think you don't need at all Priamrey Key in Product has warehouseKey
One problem with this, specific to MySQL and InnoDB storage, is that InnoDB will silently create an extra 6-byte integer internally to serve as a surrogate primary key. Also, queries against any InnoDB table are more efficient if you can do them via the primary key. So it's to your advantage to define a primary key (or unique key) if possible.
If the combination of columns Product_ID, Warehouse_ID aren't sufficient to uniquely identify every row, then you could add a third column to distinguish between duplicates. For example, Stock_ID or something.