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.)
Related
I have a MySql database with a Users table:
create table Users
(
Id varchar(255) charset utf8mb4 not null primary key,
ProfileId int auto_increment,
#other fields
);
ProfileId field is used as a foreign key for many tables. E.g.:
create table Fingerprints
(
Id int auto_increment primary key,
ProfileId int null,
constraint FK_Fingerprints_Users_ProfileId
foreign key (ProfileId) references Users (ProfileId)
);
I have two Users records and want to swap their ProfileIds without any other changes. How can I do it? I would prefer not to drop foreign key constrain because the database is on production and there are a lot of related tables where I have to do that.
Update:
The data is the following:
User1: ProfileId = 1,
User2: ProfileId = 2
#the other field doesn't matter
I want to swap their profileIds, so user1 contained user2's data from the related table by foreign key and vise versa.
Presumably, you don't want to change the foreign key relationships (they are not defined as cascading) I would suggest that you change the other columns:
update users u join
users u2
on (u2.profileid, u.profileid) in ( (#id1, #id2), (#id2, id1) )
set u.id = u2.id,
u.others = u2.others;
I'm trying my first hand at creating a mysql database for a simple blog. I'm having trouble understanding foreign keys and their appropriate relations. If someone can explain in "layman's" terms I'll be very happy.
I have a table called users that has the basics of fields (username, email, password etc) which I've created a user_type field and set it to INT. I've created the corresponding table called user_type and added two fields (one being the type_id = primary key and the other been the type = VARCHAR).
My question is:
Am I correct in understanding that I connect the two tables together by setting the foreign key link from the user_type INT in the users table to reference the type_id from the user_type table?
Your understanding is correct.
From SQL FOREIGN KEY Constraint
A FOREIGN KEY in one table points to a PRIMARY KEY in another table.
So in your example, the user_type id in table user_types would be the primary key, and the user_type int in table users would be the foreign key entry.
This enforces that an entry in table user_types has to exist before it can be used in table users.
You referencing from user to usertype:
n users have one user_type
If you create the table with an sql statement it should include something like this in the user part:
DROP TABLE IF EXISTS `user` ;
CREATE TABLE IF NOT EXISTS `user` (
`ID` INT NOT NULL AUTO_INCREMENT ,
`username` VARCHAR(55) NOT NULL ,
`email` VARCHAR(55) NOT NULL ,
`password` VARCHAR(55) NOT NULL ,
`user_type` INT NOT NULL ,
PRIMARY KEY (`ID`) ,
INDEX `user_to_usertype_idx` (`user_type` ASC) ,
CONSTRAINT `user_to_usertype`
FOREIGN KEY (`user_type` )
REFERENCES `user_type` (`type_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
You have to create user_type before you create user, otherwise you will get a failure.
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.
I have 2 tables, customers and affiliates. I need to make sure that customers.email and affiliates.email are exclusive. In other words, a person cannot be both a customer and an affiliate. It's basically the opposite of a foreign key. Is there a way to do this?
You can use a table that stores emails and have unique constrain on the email, and reference that table from the customer and affiliate. (still need to ensure that there are no 2 records referencing the same key)
You can use trigger before insert and before update to check if the email is not present.
Or you can leave this validation to the application logic - not in the database, but in the applicationc ode.
There is no key you can do this with, but it sounds like you shouldn't be using two tables. Instead, you can have one table with either customer/affiliate data (that needs to be unique in this table) and another table that has the type (customer/affiliate).
CREATE TABLE People (
pplid,
pplEmail,
ptid,
UNIQUE KEY (pplEmail)
)
CREATE TABLE PeopleType (
ptid,
ptType
)
INSERT INTO PeopleType VALUES (1, 'affiliates'), (2, 'customers');
You can try the following.
Create a new table, which will be a master for customers and affiliates:
CREATE TABLE party
(
id int not null auto_increment primary key ,
party_type enum('customer','affiliate') not null,
email varchar(100),
UNIQUE (id,party_type)
);
--Then
CREATE TABLE customer
(
....
party_id INT NOT NULL,
party_type enum('customer') NOT NULL DEFAULT 'customer',
PRIMARY KEY (party_id,party_type)
FOREIGN KEY (party_id,party_type) REFERENCES party(id,party_type)
);
CREATE TABLE affiliates
(
....
party_id INT NOT NULL,
party_type enum('affiliate') NOT NULL DEFAULT 'affiliate',
PRIMARY KEY (party_id,party_type)
FOREIGN KEY (party_id,party_type) REFERENCES party(id,party_type)
)
-- enum is used because mysql still doesn't have CHECK constraints
This way each party can be only of one type
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.