I made a database called users in which it has a name, password and phone number, but I want this user to have another table that stores current_capital, current_percentage and current_date of that user but I do not know how to do it, some advice ?
I have the telephone number in the user database as the primary key.
It is advisable to have a database for each user? or better to these attributes (save capital_actual, current_percent and current_date) I add an attribute identifier_user that would be the phone number and put everything in a second table? (as records table)
Thanks.
When using databases, you want to have a data model with a fixed set of tables and columns. You then add data by adding rows to tables. Not tables to databases, or columns to tables, but rows to tables.
From what I can tell, you have two tables connected using a foreign key constraint:
create table users (
user_id int auto_increment primary key,
phone_number varchar(255),
password varchar(255), -- should be encrypted
name varchar(255)
);
create table user_daily (
user_daily_id int auto_increment primary key,
user_id int,
current_date date,
current_capital numeric(10, 2),
current_percent numeric(5, 4),
constraint fk_user_daily_users foreign key (user_id) references users(user_id)
);
Note that both tables have auto-incrementing primary keys.
Related
At a workplace they recycle punchcard ids (for some strange reason). So it is common to have past employees clashing with current employees. As a workaround I want to have employee punchcard id, employee name+surname as the unique primary key (fingers crossed, perhaps add date-of-birth and even passport if available). That can be accomplished with
PRIMARY KEY (pid,name,surname).
The complication is that another table now wants to reference an employee by its above primary key.
Alas, said PK has no name! How can I reference it?
I tried these but no joy:
PRIMARY KEY id (pid, name, surname),
INDEX id (pid, name, surname),
PRIMARY KEY id,
INDEX id (pid, name, surname) PRIMARY KEY,
Can you advise on how to achieve this or even how to reference a composite primary key?
Update:
The table to store employees is em.
The table which references an employee is co (a comment made by an employee).
Ideally I would use pid (punchcard id) as the unique id of each employee. But since pids are recycled, this is not unique. And so I resorted to creating a composite key or an index which will be unique and can reference that as a unique employee id. Below are the 2 tables without the composite key. For brevity, I abbreviated table names and omitted surname etc. So the question is, how can I reference an employee whose id is composite from another table co.
CREATE TABLE em (
pid INT NOT NULL,
name VARCHAR(10) NOT NULL
);
CREATE TABLE co (
id INT primary key auto_increment,
em INT,
content VARCHAR(100) NOT NULL,
constraint co2em_em_fk foreign key (em) references em(pid)
);
If another table wants to reference this one by a composite key, you don't need it to have a name - just the list of fields will do. E.g.
CREATE TABLE other_table (
ID INT PRIMARY KEY AUTO_INCREMENT,
pid *defintion*,
name *defintion*,
surname *defintion*,
..., -- other fields, keys etc.
FOREIGN KEY (pid, name, surname) REFERENCES employees(pid, name, surname)
);
UPD: If you expect that the set of the fields inside PK might change and you can't make a simpler PK (auto-increment integer for example) for the original table, then your best bet might be something like this:
CREATE TABLE employee_key (
ID INT PRIMARY KEY AUTO_INCREMENT,
pid *defintion*,
name *defintion*,
surname *defintion*,
FOREIGN KEY (pid, name, surname) REFERENCES employees(pid, name, surname)
);
-- and then reference the employees from other tables by the key from employee_key:
CREATE TABLE other_table(
ID INT AUTO_INCREMENT PRIMARY KEY,
employee_id INT NOT NULL,
... -- other fields, indexes, etc...
FOREIGN KEY (employee_id) REFERENCES employee_key(ID)
);
Then if you have a change in employee table PK, you'll only need to update employee itself and employee_key, any other tables would stay as is.
If you CAN, however, change the original employees table, I would recommend something like this:
CREATE TABLE employees(
ID INT PRIMARY KEY AUTO_INCREMENT,
pid *defintion*,
name *defintion*,
surname *defintion*,
... -- other fields, keys, etc.
UNIQUE KEY (pid, name, surname)
);
Then you'll have to maintain the logic of generating new pid's in your code, though, or have them in some side table.
UPD2: Regarding inserts and updates.
As for inserts: you need to insert these explicitly - otherwise how would you expect the relation to be established? If you're using an ORM library to communicate with your database, then it might provide you with the methods to specify linked objects without explicitly adding the IDs, but otherwise to insert a row into employees, employee_key and other_table you need to first INSERT INTO employees(...) ;, then get perform a separate INSERT for the employee_key (knowing the key fields you've just added to employees), get the auto-generated key from employee_key and then use that to perform inserts to any other tables.
You might simplify all this by writing an AFTER INSERT trigger for employees table (that would automatically create a row in employee_key) and/or performing your inserts via a stored procedure (that will even return back the key of the newly inserted row in employee_key). But still this work needs to be done, MySQL won't do it for you by default.
Updates are a bit easier, since you can specify ON UPDATE CASCADE when adding the foreign key - in that case a change to one of the fields in the employees will automatically trigger the same change in any tables that reference employees by this key.
You would define it
CONSTRAINT id
PRIMARY KEY (pid, name, surname)
But you should read more about how MySQL uses INDEXES and how to optimize them
https://dev.mysql.com/doc/refman/8.0/en/optimization-indexes.html
I have two tables, users table and login table.
Say:
Create table users(
id int not null,
name varchar not null,
email varchar not null,
password varchar not null,
entries int default 0,
primary key(id));
Create table login(
id int not null,
email varchar not null,
password varchar not null,
user_id int not null,
Primary key(id)),
Foreign key (user_id) references users(id));
What constraints can I add or how can i work my way around such that whenever i add a user in the users table, the email and password columns are added into the login table too (just like to say i create a minimized version of the users table which only contains login credentials of users). And whenever i delete a user from the users table, he should be removed from the login table.
I hope i have been descriptive enough😊
You can define constraint with cascade delete. To implement the update of dependent tables you need triggers. It is possible to define AFTER INSERT trigger where you can update any dependent tables.
At the same time, I would reconsider having redundant fields in the dependent table when you always can obtain it by joining with the main table.
I have the following scenario: A 'phone' child table can serve several parent tables through join tables, as follows:
CREATE TABLE phone (
id BIGINT AUTO_INCREMENT,
number VARCHAR(16) NOT NULL,
type VARCHAR(16) NOT NULL,
PRIMARY KEY(id)
);
CREATE TABLE employee_phone (
id BIGINT AUTO_INCREMENT,
employee BIGINT NOT NULL,
phone BIGINT NOT NULL,
PRIMARY KEY(id),
CONSTRAINT empl_phone_u_phone UNIQUE(phone),
CONSTRAINT empl_phone_fk_employee
FOREIGN KEY(employee)
REFERENCES employee(id) ON DELETE CASCADE,
CONSTRAINT empl_phone_fk_phone
FOREIGN KEY(phone)
REFERENCES phone(id) ON DELETE CASCADE
);
Let Alice and Bob live in the same house and be employees of the same company. HR has two phone numbers registered for Alice whereas they have only one for Bob, the number of the house's landline. Is there a way to enforce at database level that a phone number (number-type) cannot be repeated for the same employee (or supplier, or whatever parent appears later), using this configuration? Or will I have to take care of such restrictions in the application layer? I'd rather not use triggers or table denormalization (as seen in related questions on the site such as this one, which work with IDs, not with other fields), but I'm open to do so if there's no alternative. I'm using MySQL. Thanks for your attention.
If I understand correctly, you just want unique constraints on the junction tables:
alter table employee_phone add constraint unq_employeephone_employee_phone unique (employee, phone);
This will prevent duplicates for a given employee or (with the equivalent constraint) supplier.
If you want all phone numbers to be unique in the phone table, then just put a unique constraint/index on phone:
alter table phone add constraint unq_phone_phone unique (phone);
(you might want to include the type as well).
If you try to add a duplicate phone, the code will return an error.
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.
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