Is this possible to achieve? A table of Interests for example, correspond to a table of users, with foreign key user_id corresponding to user(id), can I enforce uniqueness for column interests.name on a user_id basis?
So you basically don't want multiple rows with the same interest for a single user_id, correct?
You need to create a unique constraint (index) on the combination of user_id and interest_id.
alter table interests add unique index(user_id, interest_id);
Related
I want to add complex unique key to existing table. Key contains from 4 fields (user_id, game_id, date, time).
But table have non unique rows.
I understand that I can remove all duplicate dates and after that add complex key.
Maybe exist another solution without searching all duplicate data. (like add unique ignore etc).
UPD
I searched, how can remove duplicate mysql rows - i think it's good solution.
Remove duplicates using only a MySQL query?
You can do as yAnTar advised
ALTER TABLE TABLE_NAME ADD Id INT AUTO_INCREMENT PRIMARY KEY
OR
You can add a constraint
ALTER TABLE TABLE_NAME ADD CONSTRAINT constr_ID UNIQUE (user_id, game_id, date, time)
But I think to not lose your existing data, you can add an indentity column and then make a composite key.
The proper syntax would be - ALTER TABLE Table_Name ADD UNIQUE (column_name)
Example
ALTER TABLE 0_value_addition_setup ADD UNIQUE (`value_code`)
I had to solve a similar problem. I inherited a large source table from MS Access with nearly 15000 records that did not have a primary key, which I had to normalize and make CakePHP compatible. One convention of CakePHP is that every table has a the primary key, that it is first column and that it is called 'id'. The following simple statement did the trick for me under MySQL 5.5:
ALTER TABLE `database_name`.`table_name`
ADD COLUMN `id` INT NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
This added a new column 'id' of type integer in front of the existing data ("FIRST" keyword). The AUTO_INCREMENT keyword increments the ids starting with 1. Now every dataset has a unique numerical id. (Without the AUTO_INCREMENT statement all rows are populated with id = 0).
Set Multiple Unique key into table
ALTER TABLE table_name
ADD CONSTRAINT UC_table_name UNIQUE (field1,field2);
I am providing my solution with the assumption on your business logic. Basically in my design I will allow the table to store only one record for a user-game combination. So I will add a composite key to the table.
PRIMARY KEY (`user_id`,`game_id`)
Either create an auto-increment id or a UNIQUE id and add it to the natural key you are talking about with the 4 fields. this will make every row in the table unique...
For MySQL:
ALTER TABLE MyTable ADD MyId INT AUTO_INCREMENT PRIMARY KEY;
If yourColumnName has some values doesn't unique, and now you wanna add an unique index for it. Try this:
CREATE UNIQUE INDEX [IDX_Name] ON yourTableName (yourColumnName) WHERE [id]>1963 --1963 is max(id)-1
Now, try to insert some values are exists for test.
I'm building a shop for school purposes. I have finished my shop but i didn't joined tables and used foreign keys (requirement) because i forgot..
I have a newbie 'question' about foreign keys.
PRODUCTS RATING TABLE:
rate_id (id of the rate),
rate, (stars 0 to 5)
comment (user input textarea),
user_id (id of the user who commented the product),
product_id (id of the product that was commented)
USERS TABLE:
`id` (id of the user),
`email` (email of the user),
`name` (name of the user),
`age`,
`username`,
`password`,
`profile_pic`,
`role` (ADMIN/USER)ยด
When i enter a comment on X product (if (isset($_POST['comment_rating])):
$sql = mysqli_query($link, "SELECT id FROM users WHERE username='$user_id'");
and then later:
$sql = "INSERT INTO products_rating (rate, comment, user_id, product_id)
VALUES ('$rate_text', '$comment', '$user_id', '$product_id');
FINAL: What i want to know is, what do i need to change in my code if i add a foreign key? And should i add a foreign key in this particular case? I must interligate all tables, and I don't understand much about joins / foreign keys. If i wasn't clear let me know. Thank you for you help!
The idea of a foreign key is pretty straightforward.
In the products_rating table, we are storing a value for user_id.
And the value that we stored there is a value of id column from a row in the user table. This establishes a relationship between the row in products_rating an a row in user.
We could get the name and email address of the user that left a product rating
SELECT u.name
, u.email
, r.rate
, r.comment
FROM product_rating r
JOIN user u
ON u.id = r.user_id
WHERE ...
A FOREIGN KEY is a constraint that implements a rule. The rule we want to implement is that we want to allow only valid user.id values to be stored in product_rating.user_id.
For example, if we attempt to store a value of '42' in the product_rating.user_id column, the database is going to check that the value '42' appears in a row in the user table (in the id) column.
The syntax that we use to implement that constraint would be on the product_rating table:
ALTER TABLE `product_rating`
ADD CONSTRAINT -- we are adding a constraint
`FK_product_rating_user` -- the name we assign to the constraint
FOREIGN KEY -- the type of constraint
(`user_id`) -- the column(s) in this table
REFERENCES -- refer to
`user` -- the name of the "foreign" table
(`id`) -- the column(s) in the "foreign" table
We can add some additional configuration that affects behavior...
ON DELETE RESTRICT
ON UPDATE CASCADE
This implements a rule... if we attempt to assign a value to user_id column in this table, and that value is not found in a row in user table id column, an error is thrown, and the statement fails.
This rule also says that if we attempt to remove a row from user, if there are any rows in product_rating that have a user_id value that matches the id value of the row we're deleting, an error is thrown, and the statement fails.
The rule also says that we update a row in user, and assign a new value to the id column, than any rows in product_rating that have a user_id value that matches the old id value will be updated, to assign the new id value to the user_id column... preserving the relationship between the rows.
Also note that this implies a "one-to-many" relationship. A user can be related to zero, one or more product_rating. A product_rating is associated with one user. (If the user_id column allows for NULL values to be stored, a NULL value represents that the row in product_rating is not associated with any user.)
That's just a rough overview of FOREIGN KEY constraints.
The basic idea is that we establish a relationship between rows by storing a common value. In the example we use, a common value of '42' in the id column of a row in the user table, and in the user_id column of one (or more) row(s) in the product rating table.
With no foreign key constraint defined, the database allows us to store any value in the user_id column. We could store '43' or '8670', and it doesn't matter if those values appear in user.id or not.
The foreign key we defined constrains (restricts) what values we can store in the user_id column. When we attempt to add or modify a row in product_rating, the database checks the value of the user_id column, and if a non-NULL value doesn't reference a row in user, an error is raised.
Note that the foreign key constraint does not cause the user_id column to be automatically populated. If we want to establish a relationship to a row in user, we have to supply a value for user_id.
I have a table "UserDetails" in which two columns namely "EmailId" and "UserId" are set as primary key. However I don't get any key violation from the SQL engine when I try to insert duplicate values in to the table. How do I debug this?
Screenshots :
You don't have two primary keys, you have a composite primary key where two columns are considered the primary key.
This means that both columns together must be unique. Your current screenshot shows that while two records have the same email, the respective rows have different userid's, thus the primary (composite) key is unique between the two, because both the emailid and userid are not the same between the two records.
Read more about composite keys here
EDIT: I'm not entirely certain what you're trying to accomplish, but my guess is you would want userid to be the primary key, and have emailid be a unique field.
**Table 1**
BOOK(bookID,bookEdition,bookName)
where combination of (bookID,bookEdition) is used as key
**Table2**
SHELF(id,shelfCode,book)
now i want my column "book" in table2 to reference the composite key(bookID,bookEdition) in Table1.
Can any one may please guide me what is the correct way of doing this. Or may please correct me if my approach wrong
Or we cannot add foreign key constraint to tables with composite keys??
If you have a compound primary key (made up of mulitple columns), all your foreign keys also must use all columns of the PK to reference that table. So, foreign key constraints can only be added referencing to whole of the key, not to a part of key.
Either you add both bookID and bookEdition to the SHELF table (which to me makes more sense as bookID and bookEdition together can uniquely identify a book) or create a separate master table for Book (with key bookID) and reference that table in all your other tables.
I need to store multiple id's in either a field in the table or add another table to store the id's in.
Each member will basically have favourite articles. Each article has an id which is stored when the user clicks on a Add to favourites button.
My question is:
Do I create a field and in this field add the multiple id's or do I create a table to add those id's?
What is the best way to do this?
This is a many-to-many relationship, you need an additional table storing pairs of user_id and article_id (primary keys of user and article tables, respectively).
You should create a new table instead of having comma seperated values in a single column.
Keep your database normalized.
You create a separate table, this is how things work in a relational database. The other solution (comma separated list of ids in one column) will lead to an unmaintainable database. For example, what if you want to know how many times an article was favorited? You cannot write queries on a column like this.
Your table will need to store the user's id and the article's id - these refer to the primary keys of the corresponding tables. For querying, you can either use JOINs or nested SELECT queries.
As lafor already pointed out this is a many-to-many relationship and you'll end up with three tables: user, article, and favorite:
CREATE TABLE user(
id INT NOT NULL,
...
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE article (
id INT NOT NULL,
...
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE favorite (
userID INT NOT NULL,
articleID INT NOT NULL,
FOREIGN KEY (userID) REFERENCES user(id) ON DELETE CASCADE,
FOREIGN KEY (articleID) REFERENCES article(id) ON DELETE CASCADE,
PRIMARY KEY (userID, articleID)
) ENGINE=INNODB;
If you then want to select all user's favorite articles you use a JOIN:
SELECT * FROM favorite f JOIN article a ON f.articleID = a.id WHERE f.userID = ?
If you want to know why you should use this schema, I recommend reading about database normilization. With multiple IDs in a single field you would even violate the first normal form and thus land in a world of pain...