Every tutorial that I watched implemented child tables with two IDs, one ID for the table itself, and one ID that was just a reference to the parent's table ID, like so:
CREATE TABLE Car (
vin INT NOT NULL PRIMARY KEY,
person_ssn INT NOT NULL,
FOREIGN KEY (person_ssn) REFERENCES Person(ssn) -- Person's primary key
);
In my project, I'm doing a discord bot, and the only identifier that I need is the server's ID. There's no need for the child tables to be identified by something else than the server's ID, like so:
CREATE TABLE Server (
id VARCHAR(25) NOT NULL PRIMARY KEY,
name VARCHAR(255) NOT NULL
);
CREATE TABLE configuration (
server_id VARCHAR(25) NOT NULL PRIMARY KEY,
FOREIGN KEY (server_id) REFERENCES Server(id),
channel_to_message_id VARCHAR(25) NULL,
master_role_id VARCHAR(25) NULL
);
So, am I wrong in making the primary key also the reference ID to the parent table? Is the "dual ID" method a convention?
If the configurations are a weak entity, which seems plausible, your implementation is right.
Weak entities occur relatively seldom, that's why you may not have seen such in a tutorial yet.
But they exist and if the configurations are weak entities according to the logic of your model (only you can judge that in the end), everything is OK.
Related
I'm working on a Java project that has a Database developed in MySQL software, and this job consists on having an entity identified by two columns, named CPF and ID.
This entity has some multivalored attributes, like CELLPHONE, and as usual, I'm creating a new table for multivalored attributes, using the PRIMARY KEY(ID,CPF) identification, so we can relate the tables between them.
However, I'm not able to create multiple rows in my CELLPHONE table, and MySQL warns me Error Code: 1062. Duplicate entry 'CPF' for key 'cellphones.CPF'.
In summary, I'm trying to use a two-column primary key to identify an entity, and using this primary key to create a multivalored attribute table, but I'm not having success.
I'm leaving below my code referring to the entity where I create the two-column primary key (PESSOA) and the code referring the multivalored table I'm trying to create (TELEFONES--the CELLPHONE I mentioned above).
CREATE TABLE PESSOA(
CPF VARCHAR(12) NOT NULL UNIQUE,
ID BOOL NOT NULL,
NOME VARCHAR(40) NOT NULL,
SEXO BOOL,
FOTO BLOB,
SALDO_BANCARIO DECIMAL(5,2) NOT NULL,
PRIMARY KEY(ID,CPF)
);
CREATE TABLE TELEFONES(
CPF VARCHAR(12) NOT NULL UNIQUE,
ID BOOL NOT NULL,
NUMERO VARCHAR(15),
FOREIGN KEY (ID,CPF) REFERENCES PESSOA(ID,CPF) ON DELETE CASCADE ON UPDATE CASCADE
);
If you want to add multiple row in cellphone table then you can't add primary key on multiple field. You have to remove primary key from TELEFONES and make both row indexed. Because of two row primary key it will not accept ID and CPF duplicate row again.
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
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 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.
First of all, sorry if this might be a stupid question. I'm very new to the world of MySQL, so...
Anyway, my question is this: I'm planning on having a database that deals with (for now) two types of users, let's say Admins and Users. My aim is to have ONE table containing all users, aptly named "users". Below is a rough outline of my MySQL command (which I haven't tested yet so errors are likely):
CREATE TABLE users {
user_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_type int NOT NULL REFERENCES user_types(user_type_id),
ssn char(10) NOT NULL,
password varchar(40) NOT NULL,
first_name varchar(30) NOT NULL,
last_name varchar(30) NOT NULL,
address varchar(80) NOT NULL
} engine = InnoDB;
The "user_type" column above will refer to another table called "user_types", which lists the different user types for the website (I'm doing this for the sake of having the option to add more user types later):
CREATE TABLE user_types {
user_type_id int UNSIGNED NOT NULL PRIMARY KEY,
user_type_desc varchar(10) NOT NULL
} engine = InnoDB;
INSERT INTO user_types (user_type_id, user_type_desc) VALUES(1,'Admin'),(2,'User');
My aim is to link "Users" with "Admins"; one "User" (child) can have one "Admin" (parent), but one "Admin" (parent) can have several "Users" associated (children). The goal for me is to create a simple appointment calendar, and for that I need to connect users with their admins (one-to-one relationships in the sense that the appointment is between one user and one admin). Now the question is:
1) Is it possible to achieve this by having ONE table for all users? If so, how do I do it in a good way? Right now I was thinking of creating a table called "assignments":
CREATE TABLE assignments {
assign_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
patient_id int NOT NULL REFERENCES users(user_id),
doctor_id int NOT NULL REFERENCES users(user_id)
} engine = InnoDB;
But the above code looks strange to me; can I do that kind of foreign key linking to the same table without any dangers? Below is also the SQL 'code' for the "appointments" table:
CREATE TABLE appointments {
appointment_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
assign_id int FOREIGN KEY REFERENCES assignments(assign_id),
date_time datetime NOT NULL,
description varchar(200) NOT NULL
};
That is, every entry in the "appointments" table points to a certain assignment between an "Admin" and a "User".
2) How can I achieve the one-to-many relationship between "Admins" and "Users" in an easy way, or rather, a proper way?
Any help or suggestions would be greatly appreciated, and sorry if these questions are stupid!
Your proposed assignments table would work if you had a many-to-many relationship between Users and Admins. Since you've described the relationship as 1-to-many (one Admin may have many Users), I would simply add an admin_id column to your users table and make it a self-referencing foreign key back to the users table.
CREATE TABLE users {
user_id int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_type int NOT NULL REFERENCES user_types(user_type_id),
ssn char(10) NOT NULL,
password varchar(40) NOT NULL,
first_name varchar(30) NOT NULL,
last_name varchar(30) NOT NULL,
address varchar(80) NOT NULL,
admin_id int REFERENCES users(user_id)
} engine = InnoDB;
In the users table add admin_userid that References users(user_id)
That way, each user points back to users table to the admin user they belong to.
Using this column a doctor can list all his patients and the assignements table can be used with appointments.
But will a certain user ALWAYS get a meeting with the same doctor/admin?
What about vacations?