I'm trying to write a create table statement for the relationship above. I'm not sure if I've represented it correctly but basically every outlet has one manager and every manager manages one outlet. I believe that either one of the primary keys from either table would be able to supply the primary key to the relationship table, can I just pick either of them?
I've also been told that I don't even need to create a separate table for the relationship unless it was a many-to-many relationship?
I'd also like to have some sort of constraint (if thats the right word) where if a store cant be deleted if a manager is attached and also can't delete a manager if they are attached to an outlet.
I've written a create table statement which I think is right but i've been doing this stuff for about 2 weeks and I really have no idea if it is going to behave the way I want:
CREATE TABLE Managers
(
mgr_id int(10) NOT NULL auto_increment,
mgr_name varchar(255),
PRIMARY KEY (mgr_id)
);
CREATE TABLE Outlet
(
store_id int(10) NOT NULL auto_increment,
store_name varchar(255),
PRIMARY KEY (store_id)
);
CREATE TABLE Store_Manager
(
mgr_id int(10) DEFAULT '0' NOT NULL,
store_id int(10) DEFAULT '0' NOT NULL,
PRIMARY KEY (store_id),
FOREIGN KEY (mgr_id) REFERENCES Managers(mgr_id)
ON DELETE NO ACTION
);
Will those statements create tables that behave according to the requirements?
Thanks
Related
What is better for multiply clients?
I create training project and can't understand what's better. Create one big stock portfolio table for all broker's clients or create individual table for each client? Individual table will require add brokerage agreement id for each table's name for it indentification.
DROP TABLE IF EXISTS portfolio;
CREATE TABLE common_portfolio (
common_portfolio_id serial,
brokerage_agreement_id BIGINT UNSIGNED NOT NULL,
type_assets_id BIGINT UNSIGNED NOT NULL,
stock_id BIGINT UNSIGNED NOT NULL,
stock_num BIGINT UNSIGNED NOT NULL,
FOREIGN KEY (brokerage_agreement_id) REFERENCES brokerage_agreement (brokerage_agreement_id),
FOREIGN KEY (type_assets_id) REFERENCES type_assets (type_assets_id),
FOREIGN KEY (stock_id) REFERENCES stock (stock_id)
);
VS
DROP TABLE IF EXISTS portfolio_12345612348; -- number generate from brokerage_agreement_id
CREATE TABLE portfolio_12345612348 (
position_id serial,
type_assets_id BIGINT UNSIGNED NOT NULL,
stock_id BIGINT UNSIGNED NOT NULL,
stock_num BIGINT UNSIGNED NOT NULL,
FOREIGN KEY (type_assets_id) REFERENCES type_assets (type_assets_id),
FOREIGN KEY (stock_id) REFERENCES stock (stock_id)
);
It is always better to keep all them in same table.
Keeping each client's data in a separate table will provide you with best performance only in case when you're looking for this particular customer.
But in all other cases it will be hell: creating/deleting a client will require you to build a dynamical create/drop table statement.
When sometime later you decided to add a column, you'll need to find ALL of those tables somehow and add new column to each one of them.
Even counting number of clients will cause you to write way more code rather than just "select count" statement.
And many more cases
So, use only one table
When we create parent-child tables, does the child table need its own primary key, or should the foreign key of the parent be used as the primary key?
Example:
I have a table that stores users, which is defined like:
CREATE TABLE users (
'id' bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
'username' varchar(32),
PRIMARY KEY ('id'))
I want to make a second table that stores some more information about a user, like their favorite animals. Should that table have its own 'id' column as well as a separate foreign key for the linked user?:
CREATE TABLE users_extra_info (
'id' bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
'fk_user_id' bigint(20) UNSIGNED NOT NULL,
'fav_mammal' varchar(32),
'fav_reptile' varchar(32),
...
PRIMARY KEY ('id'),
KEY 'fk_user_id' ('fk_user_id'))
or do you usually just drop the 'id' column since the foreign key has to be unique?:
CREATE TABLE users_extra_info (
'fk_user_id' bigint(20) UNSIGNED NOT NULL,
'fav_mammal' varchar(32),
'fav_reptile' varchar(32),
...
PRIMARY KEY ('fk_user_id'))
Thanks
As a matter of principle, not related to other tables, each table should have a PRIMARY KEY in order for you to be able to distinguish one row from another. While it's not always necessary to absolutely identify individual rows that is often a requirement.
In the event of a true one-to-one relationship (or a one-to-zero-or-one relationship, which also occurs), because the foreign key is necessarily unique it can also be used as the primary key of the subsidiary table. There is absolutely no reason at all to introduce a second unique column in that case.
However, one-to-one and one-to-zero-or-one relationships are less common than one-to-many relationships. In that more common case, you cannot use only the foreign key columns as the primary key since they are not unique in the child table. In this case you can choose either to introduce an additional integer key or created a composite primary key using the foreign key column(s) and one or more other columns that, together, are guaranteed to be unique.
You have to understand the normalization rules.
Here's the link http://www.studytonight.com/dbms/database-normalization.php.
If you want to put the additional columns to another table, I don't see a reason to have an extra id column. Below is what I would do. Another benefit from this approach is that you ensure 1 to 1 relationship. If you had a separate ID column, you would be able to have many rows in users_extra_info linked to one row in users.
CREATE TABLE users (
id int,
username varchar(32),
PRIMARY KEY (id));
CREATE TABLE users_extra_info (
fk_user_id int,
fav_mammal varchar(32),
fav_reptile varchar(32),
PRIMARY KEY (fk_user_id),
foreign key (fk_user_id) references users(id));
You can also think about cascading deletion.
I am not sure how to phrase the question so I'll illustrate the tables and the explain what I want to achieve.
-- static table of the entity classes supported by the application
create table entity_type (
id integer not null auto_increment,
name varchar(30) not null,
primary key(id)
);
-- static table of statuses supported by the application
create table entity_status (
id integer not null auto_increment,
name varchar(30) not null,
primary key(id)
);
-- table of valid combinations
create table entity_type_entity_status_link (
entity_type_id integer not null,
entity_status_id integer not null,
unique key(entity_type_id, entity_status_id),
foreign key(entity_type_id) references entity_type(id),
foreign key(entity_status_id) references entity_status(id),
);
-- The tables where user types and statuses are defined
create table user_type (
id integer not null auto_increment,
name varchar(30) not null,
entity_type_id integer not null,
primary key(id),
foreign key(entity_type_id) references entity_type(id)
);
create table user_status (
id integer not null auto_increment,
name varchar(30) not null,
entity_status_id integer not null,
primary key(id),
foreign key(entity_status_id) references entity_status(id)
);
-- table of valid pairs
create table user_type_user_status_link (
user_type_id integer not null,
user_status_id integer not null,
unique key(user_type_id, user_status_id),
foreign key(user_type_id) references user_type(id),
foreign key(user_status_id) references user_status(id),
);
The basic premise behind these tables is that the system supports core types and statuses and the user is able to create their own user types and statues that derive from these.
The question I have is that I cannot see a way of creating any database constraints on the user_type_user_status_link table to ensure that the you cannot insert a file_type - file_status pair where the parent entity_type - entity_status is itself not valid. Or is this something that would have to be done with triggers.
The basic premise behind these tables is that the system supports core
types and statuses and the user is able to create their own user types
and statues that derive from these.
Although that sounds like a laudable goal on the surface, the effect is to delegate database design to your users. Database design, because the effect of your desire to set foreign key references to a subset of the rows in entity_type_entity_status_link means each of those subsets is a defacto, unnamed table.
This approach never ends well.
What you've developed is the "One True Lookup Table". Google that for a host of reasons why OTLT is an anti-pattern.
The best solution is to model real things in your tables. (Entity isn't a real thing. It's an abstraction of a real thing.) Something along the lines of either
create table file_status (
file_status varchar(30) primary key
);
or
create table file_status (
file_status_id integer primary key,
file_status varchar(30) not null unique
);
would work well for file statuses.
In the case of the second one, you can set a foreign key reference to either the id number (saves space, requires an additional join) or to the status text (takes more space, eliminates a join). Note that you need the unique constraint on the status text; your original design allows the user to enter the same text multiple times. (You could end up with 30 rows where entity_type.name is 'File'.
You should use triggers for that.
MySQL does not support constraints of the form that will prevent what you want.
I have two tables: one for areas (like science, sport, education), and another for professions (like scientist, designer, golf player). There is a foreign relationship between the two tables, which works without any problems at the moment.
But now I need another table to put "number of workers", "average age", "years in the company" (this list is possibly different for each profession). What is the best way to do this? Create another table? What would be the parent? Basically, it is a third statement.
CREATE TABLE group (
id smallint(5) unsigned NOT NULL auto_increment,
area varchar(30),
PRIMARY KEY (id)
)
CREATE TABLE job (
ref int(10) unsigned NOT NULL auto_increment,
jobid smallint(5) unsigned NOT NULL,
job varchar(50),
PRIMARY KEY (ref)
)
ALTER TABLE job
ADD CONSTRAINT FK_job
FOREIGN KEY (jobid) REFERENCES group(id)
ON UPDATE CASCADE
ON DELETE CASCADE;
From what I understand I would set up a third table as follows
Table: Employee
First_Name varchar(30)
Last Name varchar(30)
Age (int(3))
Employment Date (DATE)
Active (Yes/No)
JobFK (Points to emprego.PK)
With this kind of setup you can use joins on your tables to calculate how many workers are in the same profession. The average age of those employees, and how long they have been with the company. Given more information about your current tables I could even describe the sql queries for that information.
I've two tables one about Customers and the second one is about their Accounts as 'Customer_Account_Information'. we know that one customer can have only one account, so I'm trying to enforce one to one relationship, but i don't know the procedure/syntax in mySql or mySqlyog.
is there any one who can help me?
You should create a Foreign Key contraint on table Accounts to table Customers using CustomerID.
Have a look at FOREIGN KEY Constraints
Also then make this a Unique Column in table Accounts
Have a look at MySQL foreign keys - how to enforce one-to-one across tables?
You could also use the same CustomerID from table Customers as PRIMARY KEY column in table Accounts as PRIMARY KEY.
A simple implementation
This is not a perfect solution but it is easy to understand with a little bit of experience with mysql and referential integrity.
You need a FOREIGN KEY in customers to refer to customer_account_inforamtion. Since the account_id in customers is the only way to join the tables, no customer can have more than one record in customer_account_information.
In the sample definitions below, I've included a FOREIGN KEY CONSTRAINT which causes the customer to be deleted when their account information is deleted. You may or may not want/need this.
CREATE TABLE customer_account_information (
id int(11) NOT NULL auto_increment,
some_attribute varchar(20) NOT NULL,
another_attribute varchar(30) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE customers (
id int(11) NOT NULL auto_increment,
account_id int(11) NOT NULL,
firstname varchar(30) NOT NULL,
surname varchar(30) NOT NULL,
PRIMARY KEY (id),
INDEX account_id (account_id),
CONSTRAINT account_id FOREIGN KEY (account_id) REFERENCES customer_account_information (id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
The account_id in customers is the foreign key which refers to a record in customer_account_information
Alternative implementation
It might be an idea to revisit the design of the two tables. If each customer really can have only one account then perhaps all of the attributes of each can be merged into one table. Yes this business rule may change in the future but it would be a better idea to defer this work until really necessary - don't over engineer the solution today.