I have table visitors and table users. Each visitor can be created by only one user and contains field visitors.userId.
So, any another user from table users can edit or delete one or more visitors.
I have created a third table events_log for logging actions like edit/delete:
Visitors_log
id | userId | visitorId | action
This table stores information about user who did actions over table visitors.
Which relationship should be between table visitors_log and rest two: users and visitors?
Now I have this Db scheme:
My opinion is: visitors_log can have one or more rows. So relations is one to many. In the same time visitors_log can contain one or more users. So, where I am wrong? Now it is one to one relation.
Is there a possibility that the user_id of a visitor could ever change ?
If the answer is yes, then you would better take the safe approach and have two foreign keys in the log, referencing the concerned visitor and the user that commited the action.
In MySQL :
CREATE TABLE visitors_log (
idVisitorLog INT AUTO_INCREMENT,
idVisitor INT NOT NULL,
idUser INT NOT NULL,
action VARCHAR(100) NOT NULL,
date_action DATETIME NOT NULL,
PRIMARY KEY (idVisitorLog),
FOREIGN KEY (visitor_log_idVisitor) REFERENCES visitors(idVisitor),
FOREIGN KEY (visitor_log_idUser) REFERENCES users(idUser)
);
PS : you probably want a date column too in the log table, I added one.
On the other hand, if the user a visitor is assigned to can never change over time, then your design can be simplified. In the log table, you could just store a foreign key to the visitors table. As the visitor stores a (fixed) user id, you do not need to duplicate that information in the log.
Related
I am creating an application like trello for that i am using MySQL as an database till now i have created authentication system using MySQL and express,node js now i want to create table for cards to save the data so, i want to know how can i link the users data to the users name.
I have created a table users with the following field id(primary key, auto_increment),name,email,password
now i want to create a table card in which the users card would be present so how can i link user table column correspond to the particular
use, thanks in advance really new to backed
Maybe this lines of code can help you out a little. To get a better grasp of the topic.
-- This statement creates the cards table you may want to use (alternatively see Barmars Comment, this maybe a more professional solution)
CREATE TABLE Cards (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
customer_id INT,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50)
)
-- This statement then "connects" the tables. It makes the customer_id in the cards table a foreign key of the primary key of the customers table.
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
After implementing this you can use JOIN in your queries to query multiple tables.
If you want more info, this video can help you understand the topic:
https://www.youtube.com/watch?v=USaXlErI-QE
I have created 2 table in 2 different databases. First database name is user which contains userDetails table, which have id as a primary key and user_name, and my second database is customer which have 1 table called as customerDetails, which have 1 id as a primary key and customer name and one view of above user table which contains id of that user table and name.
So what i want to do is, creating a foreign key of that view in customerDetails table, so that i can access user table from customer database through view. I don't know how to achieve this, as i am new to database concepts please anyone can get me out of this.
Whole scenario is as follow,
> Database Name : user
> Table Name : userDetails
> Fields : id userName
>
> Database Name : customer
> View Name : user_view
> Fields : id userName
>
> Database Name : customer
> View Name : customerDetails
> Fields : id custName
i want in last table that is in customerDetails last column as a foreign key from view. How can i achieve this?
Views are not related to foreign keys as much as getting to your data as mentioned in comments by your peers. The below uses a Junction Table to intersect users and companies, enforcing a Foreign Key constraint between databases (not a bad idea for shared info between databases).
The Junction Table is many-to-many, and hooks users and companies together.
Schema:
create schema userDB;
create table userDB.userDetails
( id int auto_increment primary key,
userName varchar(100) not null
);
create schema customerDB;
create table customerDB.customerDetails
( id int auto_increment primary key,
custName varchar(100) not null
);
create table customerDB.userCustomerJunction
( -- a many-to-many mapping
id int auto_increment primary key,
userId int not null,
custId int not null,
unique key (userId,custId), -- no dupes allowed
foreign key `ucj_2_user` (userId) references userDB.userDetails(id),
foreign key `ucj_2_cust` (custId) references customerDb.customerDetails(id)
);
Test it:
insert customerDB.customerDetails(custName) values ('Exxon Mobil'); -- id 1
insert customerDB.userCustomerJunction(userId,custId) values (1,7); -- FK Failure
-- above line generates an error 1452 as expected
insert userDB.userDetails(userName) values ('Kelly'); -- id 1
insert customerDB.userCustomerJunction(userId,custId) values (1,1); -- success, FK's satisfied
Remember that the user and company are separate entities and to interface the two would require something that ties them together. A Junction table is a fantastic place to put a column such as effectiveRights or something. It would denote what the user can do, such as insert, update, delete, view, blacklist, etc.
Creating a view between user and company is simply like any join, but in this case it would be between databases with the whichDB. in front of the table name. The view is materialized and manifested in the physical tables. So as the physical rules, the physical has the FK's in force (data integrity). And the addition of an effectiveRights column will assist you in determining what each user and company can do together: such as, yes, this user has certain rights to this company info, etc. With a rights bitmark, or separate columns for rights, all in the Junction table. For an example of Junction tables, see this Answer of mine.
Consider two tables User and UserDetails
User (UserID,Name,Password)
UserDetails(UserID,FullName, Mobile Number,EMail)
First I will enter details into User table
Then Afterwards I wish to enter details into UserDetails Table with respect to primary key of first table i.e., UserID which is autoincremented.
consider this scenario..
User: (101, abc, xyz), (102,asd,war)
Now i want to store details in second table with respect to Primary key where UserID= 102
How can I accomplish this?
Start over with the design. Here is a start that runs through and doesn't blow up. Do the same for email. Keep data normalized and don't cause unnecessary lookups. When you have a lot of constraints, it is a sign that you care about the quality of your data. Not that you don't without constraints, if they are un-constrainable.
We all read on the internet how we should keep main info in one table and details in another. Nice as a broad brush stroke. But yours does not rise to that level. Yours would have way too many tables. See Note1 at bottom about about Entities. See Note2 at bottom about performance. See any of us with any broad or specific question you may have.
create table user
( userId int auto_increment primary key,
fullName varchar(100) not null
-- other columns
);
create table phoneType
( phoneType int auto_increment primary key, -- here is the code
long_description varchar(100) not null
-- other columns
);
create table userPhone
( id int auto_increment primary key,
userId int not null,
phone varchar(20) not null,
phoneType int not null,
-- other columns
CONSTRAINT fk_up_2_user FOREIGN KEY (userId) REFERENCES user(userId),
CONSTRAINT fk_up_2_phoneType FOREIGN KEY (phoneType) REFERENCES phoneType(phoneType)
);
Note1:
I suspect that your second table as you call it is really a third table, as you try to bring in missing information that really belongs in the Entity.
Entities
Many have come before you crafting our ideas as we slug it out in design. Many bad choices have been made and by yours truly. A good read is third normal form (3NF) for data normalization techniques.
Note2:
Performance. Performance needs to be measured both in real-time user and in developer problem solving of data that has run amok. Many developers spend significant time doing data patches for schemas that did not enforce data integrity. So factor that into performance, because those hours add up in those split seconds of User Experience (UX).
You can try this:-
INSERT INTO userDetails
(SELECT UserID, Name FROM User WHERE USerID= 102), 'Mob_No', EMail;
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 have a table that contains account information for various entities in the database. Currently the table design is something like:
CREATE TABLE account (id int(11) NOT NULL auto_increment,
account_id int(11) NOT NULL,
account_type varchar(15) NOT NULL,
balance decimal(12,2) NOT NULL,
PRIMARY KEY (id))
The account_id column references (not database enforced) one of 3 tables. The account_type column tells the programmer which table to reference. I do not like this approach, because I cannot enforce the relationship and the programmers can accidentally corrupt the data. I have considered doing one of the following:
Adding a nullable foreign key for each type, or dropping the account_id column and adding a cross reference table to link the account to the entities. The account_type column would be used to tell the programmers which cross reference table to access. Are there any other options? What is the best practice for something like this?
You could try having a master identity table from which the three shared-identity tables draw their primary keys. Your account table in the question would then link to the master table. Loosely described:
MasterIdentity
Id (autoincrement)
IdentityType (string, maybe FK to a type lookup table, whatever you want)
Table1
Id (PK, FK to MasterIdentity)
other data
Table2
Id (PK, FK to MasterIdentity)
other data
Table3
Id (PK, FK to MasterIdentity)
other data
Account
Id (its own identifier as you already have)
AccountID (FK to MasterIdentity)
other data
Inserting into any of the three tables would involve inserting into MasterIdentity, grabbing the scope identity value from the insert, and inserting into the desired table directly specifying the Id. (This would all have to be atomic within a transaction, of course.) Note that the Id on the three tables are not auto-increment values, you'd provide them.
Then any table which needs to refer to those three (non-overlapping, I assume) tables would have a single table to refer to which has the identity and the type, the latter of which tells you which sub-table has the rest of that record's data.
(I'm pretty sure this is called a supertype/subtype table relationship, but I can't say for certain.)