SQL - Multiple owned items - mysql

I am making a MySQL Database. I've got a table containing basic information of people looking like this:
MySQL
create table TBL_Pers (
Clientnr int,
Name varchar,
Post char(6),
Cont char(1),
Contdr tinyint,
p_p_a smallmoney)
Moving on, I have got a table with info about the printers in the database like so:
MySQL
create table TBL_Printer (
PNr int,
PBrand varchar,
PName varchar,
Serialnr varchar)
So here comes my question:
Let's say we have 3 different kinds of printers in TBL_Printer and a person owns 2 of them. How do I fill in that information in TBL_Pers so I can extract that information with PHP (To generate the owned printers in a overview on a webpage)?

Use another table to relate both
CREATE TABLE person_printer
(
person int not null,
printer int not null,
PRIMARY KEY (person, printer)
)

You'd better add a third table to connect these two tables.But if you only have three kind of printer you just need to add three colums to the TBL_Pers for each printer.If he or she owns one "1" to the column else fill "0".

Related

same Column name in multiple tables

I am building an e learning website. I have three types of users : novice, intermediate and expert. I have 3 tables: lecture,chapter and pages.For each of these table I have to differentiate them by adding for which type of user is that lecture,chapter and page.
Is this a good practice to add same column name category (which can be either novice, intermediate or expert) to all the 3 tables ?
If you want to add more characteristics later to your user categories, the best is to create a separate table for this (eg: user_categories) and refer to this table in all 3 content tables. It would look like this:
CREATE TABLE user_types (id int PRIMARY KEY, name VARCHAR(20));
CREATE TABLE lectures (id int PRIMARY KEY, user_type int REFERENCES user_types(id));
You can also refer to this post to decide how to proceed in your case:How far to take normalization in database design?

MYSQL|Datatype for states

I need to figure out which datatype to use for states.
Should it be SET or VARCHAR or anything else?
CREATE TABLE actors(
state SET('USA','Germany','....)
)
alternatively
CREATE TABLE actors(
state VARCHAR(30)
)
Assuming there's going to be tens or over hundred of the countries, it's best to use separate table.
CREATE TABLE states(
state_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(30)
);
It's also recommended to use foreign key on the state_id so if you want to delete a state from your database, it wouldn't break other data depending on it.
If each actor is going to be assigned only to one state (1:1), you can use column in the actors table.
CREATE TABLE actors(
actor_id INT ...,
state_id INT,
)
Or if each actor can be assigned to more states (1:N), use another table for these relations:
CREATE TABLE actors(
actor_id INT ...,
)
CREATE TABLE actors_to_states(
actor_id INT,
state_id INT
)
SET is a compound datatype containing values from predefined set of possible values. If table contains such a data then according to relational databases theory it is not in 1NF. So it is only few special cases where this approach is reasonable. In most cases I suggest using separate table for countries like in example below:
CREATE TABLE countries (id SMALLINT, name VARCHAR(100))
To answer these type of questions , you should so little bit of data analysis and ask some questions to your data like :
What is the maximum size of my data ?
In your case it will be the country which has the largest name .Note this down. Add 20 to remain on safe side .
Will my data always contain numbers or characters, or combination ?
In your case only characters . So it is varchar .
Also plan your data-model such that you don't need to edit afterwards .Use of set would not be recommended by me in that case.
I recommend you use the standard abbreviations (US for USA, DE for Germany) and put it in
country_code CHAR(2) CHARACTER SET ascii NOT NULL
That way, it is compact (2 bytes) and readable by users. Then, if you want, you can have another table that spells out the country names.
If an actor can belong to multiple states, then this won't work, and you do need to have a SET. If you need that, we can discuss it further.

Creating a Table in SQL, where each tuple can have mutiple values

I m try to make a Table using Create Table in SQL,
where a person can work at multiple places, and a place can have multiple person working on it,
this is what i m trying, i m sure its not correct
create table ( person char(15), place char(15), salary int)
now since a person can work in multiple places, i m confused should the tuple place has multiple values,
if yes. how do i do it
Thanks in advance
It is called a n to m relation. Use 3 tables
persons table
-------------
id int
name varchar
places table
------------
id int
name varchar
place_persons table
-------------------
place_id int
person_id int
You should create three separate tables:
"persons"
int ID (primary key, auto-increment)
varchar username
varchar email ... (all other info needed)
"places"
int ID (primary key, auto-increment)
varchar name
etc.
And the third table gives you the relationship between the two:
"person_places" (or place_persons, depends on what you like)
int ID (primary key, auto-increment)
int place_id (linked to the ID of the "places" entry)
int person_id (linked to the ID of the "persons" entry)
This way, every time a person starts working in a new place, you just add an entry to the "person_places". Same thing when they leave a place, or a place goes out of business or whatever, you just need to touch the "person_places" table.
Also, this way, one person can work in several places, just like one place can have several people working in it.
This is not normalized but it is ok to use this as you have only 3 columns and normalization will add more headache of joins and extra columns to define relationship.
suppose PersonA works in both PlaceA and PlaceB. PersonB also works in both the places but on different salaries then your data will be like this
insert into Yourtable values
('PersonA','PlaceA',1000),
('PersonA','PlaceB',2000),
('PersonB','PlaceA',1100),
('PersonB','PlaceB',1200),
('PersonC','PlaceA',1000)
and if you want to know that how many places PersonA works then you query will be
select place from YourTable where person = 'PersonA'
This way you don't need to save multiple values in same tuple.

Linking values in MySQL

I am making a page for a website where customers of the website that rented/bought printers from the company can fill in the amount of printed documents (of every printer they own) in the last period.
Now, I need to translate this to MySQL. The idea is when the customer logs in the webpage it loads an overview with the printers they own, all of them in seperate boxes.
Those boxes each get an input field for the number they are required to submit.
So to make this work I need to put in a Database that, for example, a customer owns 6 different types of printers.
MySQL
--Table for Customers--
create table TBL_Pers (
Clientnr int,
Name varchar,
Post char(6),
Cont char(1),
Contdr tinyint,
p_p_a smallmoney)
--Table for Printer--
create table TBL_Printer (
PNr int,
PBrand varchar,
PName varchar,
Serialnr varchar)
The problem I run with is I have no clue how to link those different printers to a person let alone if I have to deal with 200 customers and 15 different kinds of printers the company offers.
So as you could probably tell I'm pretty new with MySQL :)
You need an association table to relate the two.
This would look like:
create table TBL_Pers_Printer (
Per_Printer_Id int auto_increment primary key,
Clientnr int references TBL_Person(ClientNr),
Pnr int references TBL_Printer(Pnr)
);
You might want to include additional information in this table, such as the date the person got the printer.
What you are looking for is called "many-to-many relationship". You implement it by adding another table:
create table TBL_Pers_Printer (
LnkNr int,
ClientNr int,
PNr int,
foreign key (ClientNr) references TBL_Pers(ClientNr),
foreign key (PNr) references TBL_Printer(PrinterNr)
);
And then insert corresponding pairs of person-printer numbers into it. Here's one of a multitude of resources explaining the concept of many-to-many relationship in a relational database.
You should have a link table TBL_CustomerPrinter (Clientnr, PNr/ SerialNo) where PNr/SerialNo would be the printer, a foreign key and the clientNr would be the client.
the table will allow multiple clients like below
clientID PrinterID
1 1
1 6
1 7
2 8
i.e. define a set of rules for link table:
one client can have multiple printers
one printer can have multiple clients - here is the question - is this possible with your schema?
Basically you need a correspondence table between client and printer, and you have to define a set of rules for this.
Hope this helps

How to structure my Users Database?

I have a website that allows users to be different types. Each of these types can do specific things. I am asking if I should set up 1 table for ALL my users and store the types in an enum, or should I make different tables for each type. Now, if the only thing different was the type it would be easy for me to choose only using one table. However, here's a scenario.
The 4 users are A, B, C, D.
User A has data for:
name
email
User B has data for:
name
email
phone
User C has data for:
name
email
phone
about
User D has data for:
name
email
phone
about
address
If I were to create a single table, should I just leave different fields null for the different users? Or should I create a whole separate table for each user?
Much better if you could create a single table for all of them. Though some fileds are nullable. And add an extra column (enum) for each type of users. If you keep your current design, you will have to use some joins and unions for the records. (which adds extra overhead on the server)
CREATE TABLE users
(
ID INT,
name VARCHAR(50),
email VARCHAR(50),
phone VARCHAR(50),
about VARCHAR(50),
address VARCHAR(50),
userType ENUM() -- put types of user here
)
Another suggested design is to create two tables, one for user and the other one is for the types. The main advantage here is whenever you have another type of user, you don't have to alter the table but by adding only extra record on the user type table which will then be referenced by the users table.
CREATE TABLE UserType
(
ID INT PRIMARY KEY,
name VARCHAR(50)
)
CREATE TABLE users
(
ID INT,
name VARCHAR(50),
email VARCHAR(50),
phone VARCHAR(50),
about VARCHAR(50),
address VARCHAR(50),
TypeID INT,
CONSTRAINT rf_fk FOREIGN KEY (TypeID) REFERENCES UserType(ID)
)
Basic database design principals suggest one table for the common elements and additional tables, JOINed back to the base table, for the attributes that are unique to each type of user.
Your example suggests one and only one additional field per user-type in a straightforward inheritance hierarchy. Is that really what the data looks like, or did you simply for the example? If that's a true representation of your requirements, I might be tempted (for expedience) to use a single table. But if the real requirements are more complex, I'd bite the bullet and do it "correctly".
Try creating four tables:
Table 1: Name, email
Table 2: Name, phone
Table 3: Name, about
Table 4: Name, address
Name is your primary key on all four tables. There are no nulls in the database. You're not storing an enumerated type but derive the type from table joins:
To find all User A select all records in table 1 not in table 2
To find all User B select all records in table 2 not in table 3
To find all User C select all records in table 3 not in table 4
To find all User D select all records in table 4
You should not create tables for different people because this will lead to a bloated database. It's best to create a single table with all the fields you need. If you don't use the field, pass in null values.
I would suggest that you use 1 single table with nullable fields. And a table of something like roles.