I'm a complete beginner to SQL and I am struggling to find a solution to a pretty simple problem.
The scenario is this: When a user registers on my site they are inserted into a 'users' table with only a few columns(user_id, username, email, password, date).
I don't want to ask anymore of them when they register, however I would like each user to have an optional settings page where they can input additional user info such as forename, surname, bio etc.
To try and keep my database clean I have created a second table called 'user_info' for this info. This table includes the 'user_id' column that exists in 'users'.
What I am struggling with is linking these two tables. I want it so whenever a user is added to the 'users' table a new entry is inserted into 'user_info' with the same 'user_id'. This also needs to work for deletion of users.
So far I have gathered that the use of a FOREIGN KEY is required and have attempted to use CASCADE to solve this.
My tables look like this:
CREATE TABLE users (
user_id INT AUTO_INCREMENT NOT NULL,
username VARCHAR(20) NOT NULL default '',
email VARCHAR(100) NOT NULL default '',
password VARCHAR(100) NOT NULL default '',
create_date DATETIME NOT NULL default '0000-00-00',
PRIMARY KEY (user_id),
UNIQUE KEY (username),
UNIQUE KEY (email)
);
CREATE TABLE user_info (
user_id INT NOT NULL,
forename VARCHAR(30) NOT NULL default '',
surname VARCHAR(30) NOT NULL default '',
dob DATE NOT NULL default '0000-00-00',
location VARCHAR(30) NOT NULL default '',
PRIMARY KEY (user_id),
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE ON UPDATE CASCADE
);
I would appreciate any advice in this issue, along with any advice on general best practice!
Kind Regards
Adam
Take a look at Triggers (http://dev.mysql.com/doc/refman/5.0/en/triggers.html).
I am also just a beginner at sql and the solution provided by me might not be the best. You can deal with this problem in two ways
Finding the last inserted id in your users table and then inserting a blank record in the user_info with the fetched id.
Since your User ID is primary key, simply do this everytime when you insert:
SELECT max(USER_ID) FROM users
store the fetched result in a variable and then insert the value of variable in the user_info table
INSERT INTO user_info (user_id) VALUES ('.$theValueInTHeVariable.');
The second method is by using triggers
in this solution you can make a trigger so that whenever a new id is inserted into the users table it automatically fetches the last generated user_id and insert it into the Users_info table.
for more information on triggers refer to the following sits.
link1
link2
If you still face any problem then please post back.
Related
I'm writing a simple user login webservice and facing a problem when selecting data from a view created in phpmyadmin.
SQLs
These are my tables (not every column but the important ones).
account table
CREATE TABLE generel.account (
id INT NOT NULL auto_increment ,
username VARCHAR(15) NOT NULL ,
mail VARCHAR(30) NOT NULL ,
password VARCHAR(20) NOT NULL ,
...
PRIMARY KEY (user_id),
UNIQUE username (username),
UNIQUE `mail` (mail)
);
userstatus table
CREATE TABLE game.userstatus (
user_id INT NOT NULL ,
is_logged_in BOOLEAN NOT NULL ,
...
PRIMARY KEY `ip` (`last_known_ip`)
);
with foreign key
ALTER TABLE userstatus
ADD CONSTRAINT fk_generel.account.id
FOREIGN key (user_id)
REFERENCES generel.account(user_id)
ON DELETE CASCADE
ON UPDATE CASCADE;
Please notice the sql libraries are different (generel and game).
This is the view I want to work with:
CREATE VIEW game.gameuser_view AS
SELECT
acc.id AS user_id ,
acc.username ,
acc.password ,
acc.mail ,
usrsts.is_logged_in
...
FROM
generel.account AS acc
INNER JOIN
game.userstatus AS usrsts
ON acc.id = usrsts.user_id
Expected Behaviour
When selecting from the view the data the result should not be empty but depend on the where clause.
When inserting into the view the data should be redirected to both tables and be also selectable from the view.
Problems
cannot select from view
can insert in view but still not select
data will be redirected to account table but not userstatus table
As I mentioned already I'm writing a webservice for a login and the same issues persist in there as well. (I didn't check the insert thing becouse the registration happens somewhere else.)
I was just started creating some database. Very basic, two tables only, and I add this one foreign key, JUST LIKE most tutorials.
Here's what happened, step by step...
I created table UserRole:
IDUserRole int not null auto_increment,
UserRole varchar(8) not null,
primary key (IDUserRole),
index (UserRole)
then I added some data:
IDUserRole = 1, UserRole = "ADMIN"
IDUserRole = 2, UserRole = "UKM"
then I created another table called UserName:
IDUserName int not null auto_increment,
UserName varchar(50) not null,
UserRole varchar(8) not null,
primary key (IDUserName),
index (UserRole),
constraint fkfk foreign key (UserRole) references userrole (UserRole)
on delete restrict on update cascade
then I tried to input a value in the UserRole field, on UserName table. Something's funny came up when I click on the value:
It shows not only one, but TWO values separated with '-', TWICE... Like this for the simpler picture:
ADMIN-ADMIN
UKM-UKM
ADMIN-ADMIN
UKM-UKM
In some cases, it's gone like this:
ADMIN-Lam Johannes
UKM-blablabla
SENDER-blablabla
SELLER-blbablba
...
Lam Johannes-ADMIN
blablabla-UKM
blablabla-SENDER
blbablba-SELLER
So anyone please, why did this occur? And how can I fix it?
Oh, by the way I use XAMPP, and open the database with phyMyAdmin
On my website, customers have the option of creating an event with various items (that have attributes like seller, color, etc.).
Should I have ONE database and a new table for each event? I don't know of another way to program this and splitting every customer/event into a new database seems like a bad solution, but I'm new to databases and don't know if that's stupid.
I assume that I'd have a TABLE with user IDs, a TABLE for each event, and a TABLE that links the user to the event(s) he/she created. Is this the optimal way to do this? All in one database?
Thanks!
You should have a one-to-many relationship between a user table, and an event table. The event table should have the user ID as a foreign key.
CREATE TABLE user (
id int UNSIGNED AUTO_INCREMENT NOT NULL,
name varchar(50) NOT NULL,
last_modified timestamp NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (name)
);
CREATE TABLE event (
id int UNSIGNED AUTO_INCREMENT NOT NULL,
user_id int UNSIGNED NOT NULL,
name varchar(50) NOT NULL,
description varchar(500) NOT NULL,
last_modified timestamp NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (user_id) REFERENCES user.id ON UPDATE CASCADE ON DELETE CASCADE
);
So then, you have your users, and when you add an event, you just assign the user_id to whatever user the event is for. Hopefully that gives you something to build from.
If you have a small number of event types, and the event types are very different in nature (different properties) then you may create a different table for each event type.
However usually you will create one database with one table for all the events, with a column for event type or code (if needed). You also don't need to create a table that contain all the event types, your code can contain them. You table should contain only the actual events that were fired.
I am having a very strange problem.
This is what i have, in my structure the "email" field is clearly set to unique. However when i try to register with a duplicate email, instead of giving me a fat error it lets it slide. My database is having two rows with the same email..
The problem isnt just for email, even though i have them all set to unique it allows any and every field to have duplicates..
Any suggestions as to why this may happen? The field is not set to allow null.
MYSQLi/PHP allowing duplicate entry on UNIQUE?
Nope.
It is some mistake with your code or data.
Your current table structure is
I can't see any unique key defined in the table that's why it is possible to have duplicate email, try this:
CREATE TABLE UserList
(
ID INT AUTO_INCREMENT PRIMARY KEY NOT NULL,
username VARCHAR(50) NOT NULL,
email VARCHAR(50) NOT NULL,
igname VARCHAR(50) NOT NULL,
password VARCHAR(100) NOT NULL,
verified VARCHAR(5) NOT NULL,
CONSTRAINT email_uq UNIQUE (email)
);
I'm beginning to build a stamp collecting web app. Python/flask backend (i think :)) mySQL as db. I don't know much about db design so please keep that in mind if I do some really stupid mistake in the way I thought it out. I was thinking of splitting the data into 3 tables.
users table (all the users should be added upon registration to this table)
stamps table (all stamps should reside here and only modified by me)
owned table (junction table with user_id and stamp_id as foreign keys)
Question : if I put user_id and stamp_id as primary key , there will only be one unique entry of this type for example user_1 has card_1. But user_1 might have a duplicate of card_1 so i should have 2 rows
user_1 card_1
user_1 card_1
Another problem that arises is that I want to include state of owned stamp. For example user_1 might have a card_1 in mint condition and a card_1 in bad condition. As far as I understand I can only enter one unique pair of user_1 card_1 . What can I do to get the desired result? Also if there's a better way of doing this please let me know.
Aditional question. I was using mysql workbench to try to plot the db so I have a question about the sql it generates. the CONSTRAINT "fk_gibberish", is that normal or ... why is that ?
CREATE TABLE IF NOT EXISTS `stampcollect`.`users` (
`user_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`user_username` VARCHAR(45) NULL ,
`user_password` VARCHAR(45) NULL ,
`user_email` VARCHAR(45) NULL ,
PRIMARY KEY (`user_id`) )
CREATE TABLE IF NOT EXISTS `stampcollect`.`stamps` (
`stamp_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`stamp_name` VARCHAR(45) NULL ,
PRIMARY KEY (`stamp_id`) )
CREATE TABLE IF NOT EXISTS `stampcollect`.`owned` (
`user_id` INT NOT NULL ,
`stamp_id` INT NOT NULL ,
`stamp_status` BIT NULL ,
PRIMARY KEY (`user_id`, `stamp_id`) ,
INDEX `fk_{F5DBEF0D-24E0-4AFF-A5CB-2A6A0D448C96}` (`stamp_id` ASC) ,
CONSTRAINT `fk_{22B4468E-A5FB-4702-A8A9-576AA48A0543}`
FOREIGN KEY (`user_id` )
REFERENCES `stampcollect`.`users` (`user_id` ),
CONSTRAINT `fk_{F5DBEF0D-24E0-4AFF-A5CB-2A6A0D448C96}`
FOREIGN KEY (`stamp_id` )
REFERENCES `stampcollect`.`stamps` (`stamp_id` ));
If users can own the same stamp in multiple states then the state should go in the "owned" table and be part of the key. If he can own multiple copies of the same stamp then it would make sense to have a "quantity" column in that table (not part of the key).
Add an id field with auto-increment on your owned table, and make that the primary key.
Regarding the other question: it's just Workbench generating a unique id for your foreign key. You can rename them, just keep them unique.