Composite primary key consisting of primay keys from other tables - mysql

I am working on an assignment and I'm a little rusty with my SQL basics as I mainly work with already created tables, not with creating them. I was given a database model and asked to create it. I was told the model may have errors and to just correct them. Here is a snippet of the part I am having issue with:
http://i.imgur.com/0KyMquZ.jpg
I've been trying to figure it out and Googling and researching but I'm just not sure if there's something I'm not getting or I need to adjust the model. The issue I am having is with the operation table and the connecting tables. The primary key for operation is made up of the three primary keys from the connecting tables and another primary key, date. Can that be done? If they were foreign keys in the other tables I think I could figure it out. I've been trying to figure out how to do it but mostly just trying to wrap my head around the concept of what this is showing. I just don't understand how or why. Wouldn't that composite primary key have to be in the other 3 tables are they fine split up? Shouldn't that composite primary key be referencing foreign keys in other tables? I'm just really confused. I'm ok working with databases but designing, not so much.
I would just ask my professor about it but we are never on the same page. I think I understand him in the moment and then I wind up more confused. I don't think it matters for this but it's MySQL.

Although it is technically allowable, I think that it is semantically meaningless in this case as it allows the following situation to exist.
A patient can be subject to the same operation on the same day multiple times by different doctors, but ...
the patient cannot be subject to the same operation on the same day multiple times by the same doctor, but ...
the patient can be subject to different operations from the same doctor on the same day.
To me, this primary key is nonsense and you might as well add a synthetic primary key and make these simple foreign key columns where appropriate.

There is no problem with declaring a composite PK where some of the components are also declared FKs. Logically, this is quite correct.
The effects on performance will be hard to predict. The index that Mysql builds based on the PK declaration will be hard to predict. Some queries will be sped up, others won't.

After reading the comments, I now understand my misconception. I was thinking the primary composite key is made up of primary keys, duplicates from the other tables. I realize now that the composite primary key is made up of foreign keys and one primary key: date. Thanks for the clarification.

Related

SQL - (Foreign key?) constraint to table names?

I'm curious if something like this is possible, if at all reasonable.
I have a column in a table, that's called ref_table and it points to a table that the current entry relates to. Let's say, in table table_people, Person ID 1 is a client and Person ID 3 is an employee, so respectively their ref_tables will show "table_clients" and "table_emplyees". I shouldn't have a problem keeping the values valid through PHP, but what would some ways of achieving it through SQL be?
I tried testing it with a foreign key constraint to INFROMATION_SCHEMA:
FOREIGN KEY `people_constraint_tables` (`ref_table`)
REFERENCES `INFORMATION_SCHEMA`.`COLUMNS`(`COLUMN_NAME`)
ON DELETE RESTRICT
ON UPDATE RESTRICT
No point refining it since it didn't work. It seems like there's one way to make it work but it is a dirty cheat apparently.
Would you do it with triggers? Would you do it at all? Someone with experience with MySQL tell me if that'sreasonable at all, I'd like to know. Thank you.
MySQL doesn't have the facility to do this easily. Other databases do, through generated columns or table inheritance.
Would I do this with triggers? Well, yes and no. If I had to do this with one table and I had to use MySQL and I wanted to introduce relational integrity, then triggers are the way to go. There is little other choice.
But really, I would simply have a different table for each reference type. There is a little bit of overhead in this (in terms of partially filled tables). And for some applications, a single reference table is quite convenient (internationalization comes to mind). But in general, I would stick with the standard method of a separate table for each entity with properly declared foreign key relationships.

MySQL Tables with Temp Data - Include a Primary Key?

I'm putting together a new database and I have a few tables that contain temp data.
e.g.: user requests to change password - a token is stored and then later removed.
Currently I have a primary key on these tables that will auto-increment from 1 upwards.
AUTO_INCREMENT = 1;
I don't really see any use for this primary key... I will never reference it and it will just get larger.
Should tables like this have a primary key or not?
Short answer: yes.
Long answer:
You need your table to be joinable on something If you want your table
to be clustered, you need some kind of a primary key. If your table
design does not need a primary key, rethink your design: most
probably, you are missing something. Why keep identical records? In
MySQL, the InnoDB storage engine always creates a PRIMARY KEY if you
didn't specify it explicitly, thus making an extra column you don't
have access to.
Note that a PRIMARY KEY can be composite.
If you have a many-to-many link table, you create the PRIMARY KEY on
all fields involved in the link. Thus you ensure that you don't have
two or more records describing one link.
Besides the logical consistency issues, most RDBMS engines will
benefit from including these fields in an UNIQUE index.
And since any PRIMARY KEY involves creating a UNIQUE index, you should
declare it and get both logical consistency and performance.
Here is a SO thread already have same discussion.
Some people still loves to go with your opinion. Have a look here
My personal opinion is that you should have primary keys, to identify or to make a row unique. The logic can be your program logic. Can be an auto-increment or composite or whatever it can be.

How to change primary from one attribute to another. mysql

I have a database in which I have declared a primary key. Later on in implementing the database, I realized that I will have to create an auto-incrementing surrogate key and switch my current primary key to that, as my current primary key will inevidably have multiple occurences. I have scoundered the depths of stack overflow and other sites searching for an answer, but I cannot find a reasonable solution.
Specifically, I am making this database for a fraternity, in which each member is initiated with a unique scroll number. It seemed like a good idea to use the scroll number as the primary key, until I realised that members with more than one major of study will have two tuples (one indicating each major, database has to be in 3NF). That considered, is creating a surrogate key the way to go, or is there a far more reasonable solution to the problem?
You will need a many to many relationship between members and areas of studies. So yes you'll need a surrogate key.

Editing a row in MySQL with unknown primary key/column IDs

So I'm trying to do "my own" version of phpMyAdmin in the sense that I'm trying to do a bunch of general operations to tables.
Right now, I'm stuck at the 'edit a row' operation. Is there a command to edit the last selected row that I can use? Is there something that would let me do something along the lines of
update t set <blah blah> where (select * from t limit 0,1);
I ask because I can't think of any other unique characteristics that my rows have as some primary keys are combinations of two foreign keys.
Thanks!
While you're probably expecting an answer along these lines, I'll step up and say it anyway: you should reconsider your database structure.
Combining two foreign keys together into a single primary key (alternatively, multiple primary keys) is a great way to force yourself into corners. You'll have to write a lot of custom code that will be unique to your database, which others will have a difficult time understanding, and therefore it'll be difficult to get help. It'll also become difficult to debug your own code, since you'll have problems returning to this non-standard code in the future when your project has grown.
Ideally, you should have a unique index on those two foreign keys, but have a single primary key that's automatically generated. You can use the primary key for operations like what you're suggesting, but also have fast lookup times on the foreign keys because of the index.

Should I add a autoinc primary key for the sake of having a primary key?

I have a table which needs 2 fields. One will be a foreign key, the other is not necessarily unique. There really isn't a reason that I can find to have a primary key other than having read that "every single tabel ever needs needs needs a primary key".
Edit:
Some good thoughts in here.
For clarity's sake, I will give you an example that is similar to my database needs.
Let's say have a table with product type, quantity, cost, and manufacturer.
Product type will not always be unique (say, MP3 Player), but manufacturer/product type will be unique (say, Apple MP3 Player). Forget about the various models the manufacturers make for this example. For ease, this table has a autoincrementing primary key.
I am giving a point value and logging how often these products are searched for, added to a cart, and bought for display on a list of hot items.
The way I have it layed out currently is in a second table with a FK pointing to the main table, and a second column for the total number of "popularity points" this item has gained.
The answers have seen here have made me think that perhaps I should just add a "points" column to my primary products table so that I could just track there... but that seems like I'm not normalizing my database enough.
My problem is I'm currently mostly just a hobbyist doing this for learning, and don't have the luxury of a DBA to tell me how to set up my tables, so I have to learn both the coding side and the database side.
You have to distinguish between primary key and surrogate key. Auto-incremented column would be a particular case of the latter. Your question, therefore, is twofold:
Does every table need to have a primary key?
Does every table need to have a surrogate primary key?
The answer to first question is YES except in some special cases (association table for many-to-many relationship arguably being an example of such a special case). The reason for this is that you usually need to be able (if not right now then in the future) to consistently address individual rows of that table - for updates / deletion, for example.
The answer to the second question is NO. If your table represents a core business entity then OR it can be referenced from many-to-one association, having a surrogate key is probably a good idea; but it's not absolutely necessary.
It's somewhat unclear what your table's function is; from your description it sounds like it has "collection of values" semantics (FK to "main" table + value). Certain ORMs don't support surrogate keys in such circumstances; if that's what has prompted your question it's OK to leave the surrogate (or even primary in case of bag) key off.
For the sake of having something unique and as identifier, please please please please have a primary key in every table :)
It also helps forward compaitability in case there are future schema changes and 2 values are no long unique. Plus, memory are much cheaper now, feel free to use them as investments. ;)
i am not sure how the other field looks like .. but i am guessing that it would be to ok to have a composite primary key , which is based on the FK and the other field .. but then again i dont know your exact scenario.
I would say that it's absolutely necessary to have some sort of primary key in every table.
Interestingly enough, one of the DBA's for a Viacom property once told me that there was really no discernible difference in using an INT UNSIGNED or a VARCHAR(n) as a primary key in MySQL. This was in reference to a user table with more than 64 million rows. I believe n can be decently large (<=100), but I forget the what they limited to. Unfortunately, I don't have any empirical data to back that up.
You don't HAVE to have a primary key on every table, but it is considered best practice to have them as they are almost always necessary on a normalized relational database design. If you're finding a bunch of tables you don't think need PKs, then you should revisit the design/layout of your tables. To read more on normalization see here.
A couple scenarios that I can think of where you may not need or want a PK on a table would be a table strictly for logging. (to limit performance degradation of writing the log and maintaining a unique index) and in the scenario where your just storing data used to pump through an application for test purposes.
I'll be contrary and say you shouldn't add the key if you don't have a reason for it. It is very easy to add this column later if needed.
Strictly speaking, a surrogate key is not necessary, but a primary key is.
Many people use the term "primary key" to mean a single column that is an auto-incrementing integer. But this is not an accurate definition of a primary key.
A primary key is a constraint on one or more columns that serve to identify each row uniquely. Yes, you need some way of addressing individual rows. This is a crucial characteristic of a relation (aka a table).
You say you have a foreign key and another column that is not unique. But are these two columns taken together unique? If so, you can declare a primary key constraint over these two columns.
Defining another surrogate key (also called a pseudokey -- the auto-incrementing type) is a convenience because some people don't like to have to reference two columns when selecting a single row. Or they want the freedom to change values in the other columns easily, without changing the value of the primary key by which one addresses the individual row.
This is a technique related to normalization and a pretty good practice. A key made up of an auto incrementing number has many benefits:
You have a PK that does not pertain to the data.
You never have to change the PK value
Every row will automatically have a unique identifier