I've been working on a wordpress plugin that is designed to create a character for a wordpress user using MYSQL. I'm new to php and sql. I'm currently struggling with two tables in my DB. A class table and a skill table.
The class table is comprised of the different classes a character can be. For example; a Warrior, Paladin or Wizard.
The skills table is comprised of different skills a character can use. For example; lightning bolt, slay, or heal.
I want these tables to have a relation with each other. Only certain skills from the skills tabled can be used by a class from the class table. So for example, a Paladin class can only choose the heal skill and a Warrior class can only use the slay skill. I'm just not sure what to use to make that work successfully.
I'm not sure if there's a condition that can be used on the skills table that only allows a certain class to reference certain skills. Could anyone point me in the right direction? Thanks for any help in advance!
A many-to-many relationship will do the trick here, this is what I would do.
I would create 3 tables, 1) Character 2) Skill 3) character_skill, here is a very simple example:
CREATE TABLE hero
(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
);
CREATE TABLE skill
(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255)
)
CREATE TABLE character_skill
(
id INT PRIMARY KEY AUTO_INCREMENT,
charachter_id INT,
skill_id INT,
CONSTRAINT character_skill_character_id_fk FOREIGN KEY (charachter_id) REFERENCES hero (id),
CONSTRAINT character_skill_skill_id_fk FOREIGN KEY (skill_id) REFERENCES skill (id)
);
Now you will store the characters on the hero table, and the skills on the skill table, now here is the trick, to assign a hero(Character) a skill you will add a record to the character_skill table with the id of the hero and the id of the skill. In the example I added a constraint that will only allow you to add characters and skills that where previously created in the other tables.
Then to query it, I will look for all the Skills on the character_skill table that have the same charachter id, liks so:
select
skill.name
from skill
INNER JOIN character_skill
on character_skill.skill_id = skill.id
where character_skill.charachter_id = 3
This is a very simple example.
This is the basic idea, only the skills connected in the character_skill table can be use by character with id 3
I used hero for the name of the character table because the 'character' name is reserved
Related
Currently, I'm working for my assignment project called 'Competition Management' and I don't know much about SQL and PHP. Afaik, my questions should be workout in PHP to do this or that but I'm just curious with these SQL. You can ignore the empty varchar.
2 Questions
Player Table is related to Competition and Association Table. Do I have to do something with it or just let it be?
In Competition Table, you can see config_competition field... but, the field should contain data inside it... in term of sport competition, lets say we have football sport, gaming e-sport, athlete sport, and etc... In this case, should I create a new table? If yes, how do I make it related with the Competition Table?
This is Organisation Table (who creates a competition)
CREATE TABLE organisation (
id_organisation varchar() PRIMARY KEY,
name_organisation varchar(),
password varchar()
);
This is Competition Table (Created by Organiser)
CREATE TABLE competition (
id_competition varchar() PRIMARY KEY,
name_competition varchar(),
config_competition varchar()
);
This is Association Table (participate a competition)
CREATE TABLE association (
id_association varchar() PRIMARY KEY,
name_association varchar(),
password varchar()
);
This is Player Table (registered by Association to participate player in a competition)
CREATE TABLE player (
id_player varchar() PRIMARY KEY,
name_player varchar()
);
You need to use foreign keys to refer to another table's primary keys. In that way, you can build a relationship between tables. In other words, you can connect the tables that have relationships with each other.
I can suggest you use MySQL workbench and draw an ER diagram of your project in the first phase of your project. After that, you can create a database.
Also, before all these work, you may need to look at the relational data models, one-to-many, one-to-one, and many-to-many. Then you can select the appropriate relations between tables.
For your second question below is an answer:
CREATE TABLE category (
category_id int PRIMARY KEY,
category_name varchar(),
);
CREATE TABLE competition (
id_competition varchar() PRIMARY KEY,
name_competition varchar(),
category_id int FOREIGN KEY REFERENCES category(category_id)
);
First of all, I'm from Spain so I'm sorry if I made some mistakes writing. So, I have two problems. It will be better if I give context before. I am not even junior, still learning code, and I thought that it will be a good proyect to create a web page where you can add ingredients, foods with that ingredients, etc. So I decided to start learning PHP and SQL. Now I'm trying to create a database, starting with some ingredients and two kinds of rices. My 1st problem is that I don't know if I need to create a data base for that. The second and main one is that I don't have any idea about how to get this working as I want.
See, First of all I created the table for ingredients´
CREATE TABLE ingredientes(
id int(255) auto_increment not null,
ingrediente varchar(255) not null,
CONSTRAINT pk_ingredientes PRIMARY KEY(id) )ENGINE=InnoDb;
Sorry 'cause it's on spanish :/, but nothing to hard to understand.
So I add some ingredients.
Here the pic showing them
After that I created two tables, and add ingredients to them.
CREATE TABLE arroz_con_pollo(
id int(255) auto_increment not null,
ingrediente int(255) not null,
CONSTRAINT pk_arroz_con_pollo PRIMARY KEY(id),
CONSTRAINT fk_pollo_ingredientes FOREIGN KEY(ingrediente) REFERENCES ingredientes(id) )ENGINE=InnoDb;
CREATE TABLE arroz_cubana(
id int(255) auto_increment not null,
ingrediente int(255) not null,
CONSTRAINT pk_arroz_cubana PRIMARY KEY(id),
CONSTRAINT fk_cubana_ingredientes FOREIGN KEY(ingrediente) REFERENCES ingredientes(id))ENGINE=InnoDb;
Here the picture showing the ID's.
Here
So now I spend a lot of time researching and find out that I can show the names by using this command
SELECT a.id,i.ingrediente
FROM ingredientes i, arroz_cubana a
WHERE i.id = a.id;
And have something like this
At this point, everything is, more or less, working. My issue came when I want to create a data base that keep all the names (arroz con pollo, arroz cubana...) in an only table named as 'rices' to be able to choose a name, and automatically have the ingredients there, without any complication for the user. But, I literally have no idea. I've been coding for hours without any victory on that. And I haven't see anything similar on the web so, if someone tell me how to fix that issue or how to make that idea of a web to keep ingredients and foods, I'll be very greatful.
Your data structure is messed up. SQL is not designed to have a separate table for each ingredient. Instead, you want two other tables.
The first is for dishes:
CREATE TABLE dishes (
dish_id int auto_increment not null,
name varchar(255)
);
You would then insert appropriate rows into this:
INSERT INTO dishes (name)
VALUES ('arroz_on_pollo');
Then you have another table for the ingredients:
CREATE TABLE dishes_ingredients (
dish_ingredient_id int auto_increment primary key,
dish_id int not null
ingredient_id int not null,
CONSTRAINT fk_dish_ingredientes_dish FOREIGN KEY(dish_id) REFERENCES dishes(dish_id)
CONSTRAINT fk_dish_ingredientes_dish FOREIGN KEY(ingredient_id) REFERENCES ingredientes(ingredient_id)
);
Voila! New dishes are just rows in a table, so you can get the names using a SELECT.
Notes on structure:
int(255) really makes no sense. Just use int. The number in parentheses is a width for the value when printing it and 255 is a ridiculous width.
I am a fan of naming primary keys with the table name. That way, the primary key and foreign key typically have the same name.
You should not have a table per dish. Create one table "dish", that includes a column "name". Each row represents a dish. Then create a supporting table where you list the (multiple) ingredients for each dish. Look around for a tutorial on databases, this topic is too large to explain in a stackoverflow question (or several).
And so you do not need to be able to list the table names, the way you were considering. (Which is not something SQL supports directly; different databases provide non-standard ways to do it, but as explained you do not actually need such a feature.)
Hello friends I am working on a school database system based on php mysql. the basic structure is as below:
Table Class-Details of all classes. Primary Key Class ID
Table Student-Details of all students, Primary key studentID. Foreign Key ClassID
Table Semester-Details of all Semesters, key SemesterID
Table class–Semester. This table solves many to many relation, primary key- IDs of both class and semester. Foreign Key ClassID, SemesterID
Table Subject -Details of all Subjects, key SubjectID
Table class–Subject. This table solves many to many relation, primary key- IDs of both class and semester. Foreign Key ClassID, SubjectID
Table marks- consists of student ID, Subject ID, Semester ID, Marks Achieved.Foreign Key ClassID, SemesterID, SubjectID
I have also applied foreign keys in all the tables which are referring back to the parent table. I am looking to apply integrity in my database so that a student for a particular class will automatically be assigned to subjects of that particular class.
If we try to change the subjects of the student, database should throw an error that these subjects belong to the class for which student is a part of.
I am sure this can be done using foreign key constraints. However, I am bit naive to do so. A working example is highly appreciated
ENGINE = InnoDB
AUTO_INCREMENT = 53
DEFAULT CHARACTER SET = utf8;
Ok, I'll try to help. :-) First make sure you know the syntax completely by using the MySQL Manual for creating tables.
MySQL 5.1: CREATE TABLE
Look for the sections that look like this.
reference_definition:
REFERENCES tbl_name (index_col_name,...)
[MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
[ON DELETE reference_option] <----
[ON UPDATE reference_option] <----
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION
Here is an example (...attept ...) from a child table of contact statistics that links to a contacts (people) parent table.
CREATE TABLE IF NOT EXISTS contactStats_tbl(
id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Contact ID number.',
email VARCHAR(254) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT 'E-mail address from contacts_tbl.',
subscribeTime TIMESTAMP DEFAULT '0000-00-00 00:00:00' COMMENT 'Time of subscription.',
unsubscribeTime TIMESTAMP DEFAULT '0000-00-00 00:00:00' COMMENT 'Time of unsubscription.',
totalMessages INT(4) NOT NULL COMMENT 'Number of messages sent.',
newsLetter ENUM('Y', 'N') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT 'N' COMMENT 'Newsletter subscription.',
CONSTRAINT csconstr01 FOREIGN KEY (id, email) REFERENCES contacts_db.contacts_tbl(id, email) ON UPDATE CASCADE ON DELETE RESTRICT)
ENGINE=InnoDB DEFAULT CHARACTER SET = utf8 COMMENT 'Contact statistics table.';
Essentially, with table constraints you are focusing on a time when someone attempts to DELETE or UPDATE a record in a child table containing fields that point to a parent table (foreign keys, in this case). For all of your child tables, my advice would be to set the ON DELETE options to RESTRICT (the default). But, for ON UPDATE, child tables should probably CASCADE to keep them consistent with their parents (I have not researched referential integrity for a while, but I think that's how it goes! Dang that MS Access! Don't vote me down if I am wrong. Just comment and I'll fix my answer. :-)). The best thing to do would be to make sure you know how referential integrity applies to the situation at hand. Truthfully, I forget how the ON UPDATE bit works because I have not used it in a while. :-)
Now, as far as automatically inserting field values into a record (in a secondary table) based on actively inserting a record into some other table (primary table), make sure that you are not in need of a trigger.
MySQL 5.1: CREATE TRIGGER
This should get you going. I tried! :-)
Anthony
I'm not sure how to store or insert this data. I am using PHP and MySQL.
Let's say we're trying to keep track of people who enter marathons (like jogging or whatever). So far, I have a Person table that has all my person information. Each person happens to be associated with a unique varchar(40) key. There is a table for the marathon information (Marathon). I receive the person data in an CSV that as about 130,000 rows and import that into the database.
So - now the question is... how do I deal with that association between Person and Marathon? For each Marathon, I get a huge list of participants (by that unique varchar key) that I need to import. So... If I go the foreign key route, it seems like the insert would be very heavy and cumbersome to look up the appropriate foreign key for the person. I'm not even sure how I would write that insert... I guess it would look like this:
insert into person_marathon
select p.person_id, m.marathon_id
from ( select 'person_a' as p_name, 'marathon_a' as m_name union
select 'person_b' as p_name, 'marathon_a' as m_name )
as imported_marathon_person_list
join person p
on p.person_name = imported_marathon_person_list.p_name
join marathon m
on m.marathon_name = imported_marathon_person_list.m_name
There are not a lot of marathons to deal with at one time. There a lot of people, though.
--> Should I even give the person an ID and require all the foreign keys? or just use the unique varchar(40) as the true table key? But then I would have to join tables on a varchar and that's bad. A marathon can have anywhere from 1k to 30k participants.
--> Or, I could select the person info and the marathon info from the database and join it with the marathon_person data in PHP before I send it over to MySQL.
--> Or, I guess, maybe make a temporary table, then join in the db, then insert (through PHP)? It's been already strongly suggested that I do not use temporary tables ever (this is a work thing and this isn't my database).
Edit: I am not sure on what schema to use because I'm not sure if I should be using foreign keys or not (purpose of this whole post is to answer that question) but the basic design would be something like...
create table person (
person_id int unisgned auto_incrememnt,
person_key varchar(40) not null,
primary key (person_id),
constraint uc_person_key unique (person_key)
)
create table marathon (
marathon_id int unisgned auto_incrememnt,
marathon_name varchar(60) not null,
primary key (marathon_id)
)
create table person_marathon (
person_marathon_id int unsigned auto_increment,
person_id int unsigned,
marathon_id int unsigned,
primary key (person_marathon_id),
constraint uc_person_marathon unique (person_id, marathon_id),
foreign key person_id references person (person_id),
foreign key marathon_id references marathon (marathon_id)
)
I'm going to repeat the actual question really quick.... If I choose to use a foreign key for person, how do I import all the person_marathon data with the person_id in an efficient way? The insert statement I included above is my best guess....
The person data comes in a CSV of about 130,000 rows so that is a straight import into the person table. The person data comes with a unique varchar(40) for each person.
The person_marathon data comes in a CSV for each marathon, as a list of 1,000 to 30,000 unique varchar(40)'s that represent each person who participated in that marathon.
Summary: I am using PHP. So what is the best way to write the insert/import of the person_marathon data if I am using foreign keys? Would I have to do it like the insert statement above or is there a better way?
This is a many-to-many relationship, one person can enter many marathons, one marathon can be entered by many persons. You need additional table in your data model to track this relation, for example:
CREATE TABLE persons_marathons(
personID int FOREIGN KEY REFERENCES Persons(P_Id),
marathonID int FOREIGN KEY REFERENCES Marathons(M_Id)
)
This table uses foreign key constraints. The foreign key constraint prevents from inserting bad data (for example you cannot insert a row with personID = 123 when there is no such id in Persons table), it prevents also from deletes that would destroy a link between tables (for example you cannot delete a person X when exists a record in person_marathon table witth such personID).
If this table contains the following rows:
personID | MarathonID
----------+-----------
2 | 3
3 | 3
2 | 8
3 | 8
it means that persons 2 and 3 both entered marathons 3 and 8
I have 3 tables
customer, menu, and order.
The order table is suppose to join the customer and menu tables, and contains the primary keys of both. Here's how I tried to create the order table on phpmyadmin.
create table order(
customerID int not null,
itemID int not null,
primary key (customerID, itemID),
foreign key(customerID) reference customer(ID),
foreign key(itemID) reference menu(itemID)
)
This doesn't work. What am I doing wrong?!!
order is a reserved word, try another name, or quote it, like
create table `order`(
customerID int not null,
itemID int not null,
primary key (customerID, itemID),
foreign key(customerID) reference customer(ID),
foreign key(itemID) reference menu(itemID) )
It is complaining as order is a reserved keyword. Wrapping it with backticks as #TokenMacGuy tells you to solves your problem. Here is a list of them
Furthermore, as a general rule, you can transform your entities like so to avoid problems, especially with reserved keywords:-
a) The Entity is always modeled (on paper) as singular as it represents a concept/asset/person in the real world or problem domain. eg. ORDER, CHECK, STUDENT, CAR
b) the corresponding DB Table it is transformed into can always be named using plural. The logic is that the table will contain lots of instances of that Entity. Therefore ORDERS, CHECKS, STUDENTS, CARS