Linking values in MySQL - 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

Related

Mysql Storing multi values in a column

I have a tables called userAccounts userProfiles and usersearches.
Each userAccount may have multiply Profiles. Each user may have many searches.
I have the db set up working with this. However in each search there may be several user profiles.
Ie, each user account may have a profile for each member of their family.
They then want to search and include all or some of their family members in their search. The way i would kinda like it to work is have a column in user searches called profiles and basically have a list of profileID that are included in that search. (But as far as i know, you can't do this in sql)
The only way i can think i can do this is have 10 columns called profile1, profile2 ... profile10 and place each profileid into the column and 0 or null in the unused space. (but this is clearly messy )
Creating columns of the form name1...nameN is a clear violation of the Zero, One or Infinity Rule of database normalization. Arbitrarily having ten of them is not the right approach, that's an assumption that will prove to be either wildly generous or too constrained most of the time. Since you're using a relational database, try and store your data relationally.
Consider the schema:
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
name VARCHAR(255),
UNIQUE KEY index_on_name (name)
);
CREATE TABLE profiles (
id INT PRIMARY KEY AUTO_INCREMENT NOT NULL,
user_id INT NOT NULL,
name VARCHAR(255),
email VARCHAR(255),
KEY index_on_user_id (user_id)
);
With that you can create zero or more profile records as required. You can also add or remove fields from the profile records without impacting the main user records.
If you ever want to search for all profiles associated with a user:
SELECT ... FROM profiles
LEFT JOIN users ON
users.id=profiles.user_id
WHERE users.name=?
Using a simple JOIN or subquery you can easily exercise this relationship.

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?

SQL - Multiple owned items

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".

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.

Two tables with same columns or one table with additional column?

Say I have two tables (Apples and Oranges) with the same columns and just a different table name. Would there be any advantages/disadvantages to turning this into one table (lets say its called Fruit) with an additional column 'type' which would then either store a value of Apple or Orange?
Edit to clarify:
CREATE TABLE apples
(
id int,
weight int,
variety varchar(255)
)
CREATE TABLE oranges
(
id int,
weight int,
variety varchar(255)
)
OR
CREATE TABLE fruit
(
id int,
weight int,
variety varchar(255),
type ENUM('apple', 'orange')
)
Depends on constraints:
Do you have foreign keys or CHECKs on apples that don't exist on oranges (or vice-versa)?
Do you need to keep keys unique across both tables (so no apple can have the same ID as some orange)?
If the answers on these two questions are: "yes" and "no", keep the tables separate (so constraints can be made table-specific1).
If the answers are: "no" and "yes", merge them together (so you can crate a key that spans both).
If the answers are: "yes" and "yes", consider emulating inheritance2:
1 Lookup data is a typical example of tables that look similar, yet must be kept separate so FKs can be kept separate.
2 Specifically, this is the "all classes in separate tables" strategy for representing inheritance (aka. category, subclassing, subtyping, generalization hierarchy etc.). You might want to take a look at this post for more info.
If there really is not any further business rules (and resultant underlying data requirements) that separate the two sub-types then I would use one table with an fk to a FruitType lookup table.
You dont mention what you will be using to access the schema which may affect which approach you take (e.g. if you are using a platform which provides an ORM to your database then this may be worth noting).
The advantage would be normalization. Your tables would then be in 2NF (second normal form).
Your fruit type would be a foreign key to a table with those fruits like so:
CREATE TABLE fruit_type (type varchar(15))
CREATE TABLE fruits (id int, weight int, variety varchar(255), type varchar(15))