I refer to the code posted here:
http://codeslayer2010.wordpress.com/2012/04/08/developer-journal-2012-03-30-building-a-php-database-connection-class-from-scratch-singleton-activerecord/
This is all well and good for tables that have a single primary key. But what about tables that have two primary keys such as a composite table? How will the design pattern in the above link account for that? For as you can see, the load function in table.class.php only takes in a single id.
The only thing I can think of for a class representing a composite table is to extend the table class and override the load function, replacing it with one that takes in two ids. But however this seems messy and I was wondering if there was a neater way to accommodate the occurrence of composite tables.
Your thoughts on this matter would be greatly appreciated.
I would recommend to extend the structure of the table to have another column, which is the primary key. And set your current two columns to a combined unique key, so you can still be sure that the data is unique, but call it with one single value as primary key.
Related
Is it possible to add a constraint that checks that TWO columns are unique in PostgreSQL 10? I've looked around but I can't find anything related to my specific need.
My issue is that I have to keep track of individual IDs (tag), associated to secondary IDs (hub). I can't set my tag IDs to be unique because they'll appear multiple times associated to hub IDs. I also can't set hub IDs unique because they'll have a bunch of tag IDs associated to them.
Is there a way to say (tag 123 and hub 456) unique, but tag 123 can still be logged if hub is 789, and vice versa?
The root of this is because the ON CONSTRAINT DO UPDATE doesn't seem to work without unique constraints, and I'm now stuck.
References, solutions, other related problems that were solved, any help is appreciated!
You need to define a primary key made of those two columns. This way you can have two or more rows in your table with the same value on the first column of the primary key, but different values on the second column, and vice versa.
Also, if you don't already, you can use pgAdmin, which is a visual tool that helps you create a database and defining tables, columns, data types, constraints, primary keys, etc. with an easy user interface.
indexes can be on multiple columns
CREATE UNIQUE INDEX name ON table (tag,hub);
11.6. Unique Indexes
thanks in advance for any help.
I have a question about foreign keys. I understand the concept of having the data from one table inserted into another for reference. But my question is, how does it get there?
Currently I have two tables and two forms. One form inserts data into table A, the other form inserts into B. Then I use a function to get the id from the last insert into A and insert it into B. Is this the proper way to do this or am I missing something?
There are two possibilities :
You know the primary key before the insertion in table A => Then your technique isn't the right one, since you're retrieving something you already added.
You don't know it (Example: auto-incremented id's) => Then your technique is the right one, and I don't think there is any other better way to achieve what you are asking for.
Note that what I called the primary key is the primary key of the row in table A, and a foreign key for rows in table B.
Short answer, I don't believe you aren't missing anything. There are many ways to accomplish what you are after, but your explanation is probably the most used and straightforward.
Another way is to use a trigger on table A to populate table B after insert (this only works if you do not need any additional user input, like form input to insert into table B).
As you cannot insert two ids at a time, yes it was an proper way.
First inserting the record on primary table, which we knows it.
Secondly, you that last insert id using the mysqli_insert_id() function
Now insert data on foreign table using this primary key.
This is for a sort of proof of concept draft to get things working, but don't want to have completely crap code. For my database, I tried to get true foreign key relations going using innoDB, but couldn't get it.
Instead of using foreign keys, I decided to just pull mysql_insert_id() after inserts, saving it as a variable, then putting that variable into the related table.
Is this horrible? Everything seems to work well, and I'm able to connect and relate ID's as needed. What benefits would using foreign keys give me over my method (besides updates/deletes cascading)?
To create a relation (master->detail), you have to always supply the keys by yourself, either using mysql_insert_id, natural keys or key generated by your applications. The FOREIGN KEY is not going to make that work for you.
What FOREIGN KEY does is
Helping you enforce the relationship/the integrity of your data (so the "detail" record does not point to an invalid parent)
Handles deletion or key alterations of master records (ON DELETE ..., ON UPDATE ...).
It's also creating an index in your "detail"-table for the "master_id"-row if it doesn't exist yet (okay, you could also do that without FOREIGN KEY)
Has also some kind of documenting purpose for example an ERM-tool could reengineer the relationship model from your schema (okay, this point is a slight long shot)
The cost of adding the FOREIGN KEY constraint statement is small compared to its benefits.
For example, I'm doing the next action:
SELECT COUNT(id)
FROM users
WHERE unique_name = 'Wiliam'
// if Wiliam don't exists then...
INSERT INTO users
SET unique_name = 'Wiliam'
The question is, I'm doing the SELECT COUNT(id) check every time I insert a new user, despite of using an unique key or not, so... if "unique_name" has an UNIQUE key it will be better for performance than using a normal key?
What you mean is a UNIQUE CONSTRAINT on the column which will be updated. Reads will be faster, Inserts will be just a bit slower. It will still be faster than your code checking first and then inserting the value though. Just let mysql do its thing and return an error to you if the value is not unique.
You didn't say what this is for, which would help. If its part of an authentication system, then why doesn't your query include the user's password as well? If it's not, a unique indexed column used to store names isn't going to work very well in a real-world system unless you are OK with having just 1 and only Wiliam in your system. (Was that supposed to be William?)
And if that name field is really unique you do not need to use COUNT(ID) in your query. If 'unique_name' is truly unique you either get an id number returned from your query or you get nothing.
You'd want something like this:
SELECT id FROM users WHERE unique_name = 'Wiliam'
No record return, no Wiliam.
An index (unique or non-unique -- I don't know what you're after here) on unique_name will improve the performance.
Your use of 'unique key' isn't very logical so I suspect you are getting confused about the nomenclature of keys, indexes, their relationships, and the purposes for them.
KEYS in a database are used to create and identify relationships between sets of data. This is what makes the 'relational' possible in a relational database.
Keys come in 2 flavors: Primary and foreign.
PRIMARY KEYS identify each row in a table. The value or values that comprise the key must be unique.
Primary keys can be made from a single column or made of several columns (in which case it is called a composite key) that together uniquely identifies the row. Again the important thing here is uniqueness.
I use MySql's auto-increment integer data type for my primary keys.
FOREIGN KEYS identify which rows in a table have a relationship with other rows in other tables. A foreign key of a record in one table is the primary key of the related record in the other table. A foreign key is not unique -- in many-to-many relationships there are by definition multiple records with the same foreign key. They should however be indexed.
INDEXES are used by the database as a sort of short-hand method to quickly look up values, as opposed to scanning the entire table or column for a match. Think of the index in the back of a book. Much easier to find something using a book's index than by flipping through the pages looking for it.
You may also want to index a non-key column for better performance when searching on that column. What column do you use frequently in a WHERE clause? Probably should index it then.
UNIQUE INDEX is an index where all the values in it must be distinct. A column with a unique index will not let you insert a duplicate value, because it would violate the unique constraint. Primary keys are unique indexes. But unique indexes do not have to be primary keys, or even a key.
Hope that helps.
[edited for brevity]
Having a unique constraint is a good thing because it prevents insertion of duplicated entries in case your program is buggy (are you missing a "for update" clause in your select statement?) or in case someone inserts data not using your application.
You should, however, not depend on it in your application for normal operation. Lets assume unique_name is an input field a user can specify. Your application should check whether the name is unique. If it is, insert it. If it was not, tell the user.
It is a bad idea to just try the insert in all cases and see if it was successful: It will create errors in the database server logs that makes it more difficult to find real errors. And it will render your current transaction useless, which may be an issue depending on the situation
How do I retrieve a multi-column PK in MySQL?
For example I have my primary key setup as
PRIMARY KEY (donor_id,country_id)
Now if I want to get the primary key value without concatenating those 2 fields in a select query, how do I do that? I want to use this in a view (or better yet, directly in phpmaker).
It's not clear what you mean by "without concatenating". A simple
SELECT donor_id, country_id FROM table WHERE ...;
will retrieve the records; you don't need to apply a CONCATENATE() function or anything like that. This is the Right Way to select two records from a table; the fact that they both happen to be declared part of the primary key changes nothing.
No special way is needed to get the records from table that has a multi-column PK in MySQL. Things might be different if you are using an ORM. An ORM may or may have special or different syntax/features for working with tables with multi-column PK.