How to implement this rather complex concept/relation in database? - mysql

I'm creating a web application, and I have an issue trying to figure out how to layout the database tables.
I'm not much of a databases guy, but here's the issue:
For example, I want the application to be have two interfaces. First one, you create a new book. Second one, you write a new entry / page in that book (or another).
I thought of having these three tables:
Books, Authors, Entries.
Books
book_id
author_id
title
Entries
id
author_id
text
datetime
book_id
Authors
author_id
fullname
username
Of course, tables are not complete. But I'm lost on how to build the relationships between tables well. I want the author to be able to create a new book (this is by creating first entry/page in that book, so Entries table has a new record, as well as Books.) Or, to add an entry/page to a book.
Also, I'm not sure if Books table should have an entry_id column to track/count entries/pages in that book.
I know it might sound vague. But I didn't know what exactly to Google or specifically ask about. If there's a concept in SQL or a good book for a web programmer (I'm good at PHP) that focuses on building web applications with rather complex relations in database, that you can tell me about, would be much appreciated.
Thank you.

I don't think that the relations are complex: an author can create a book and a book can contain entries. Your schema allows the possibility that anybody can create an entry in a book that they didn't create - if you don't want this, then remove the 'author_id' field from the 'entries' table.
But what is your real question?

Related

MySql table with potentially *very* many columns

A friend who is a recruiter for software engineers wants me to create an app for him.
He wants to be able to search candidates' CVs based on skills.
As you can imagine, there are potentially hundreds, possibly thousands of skills.
What's the best way to represent the candidate in a table? I am thinking skill_1, skill_2, skill_n, etc, but somewhere out there there is a candidate with more than n skills.
Also, it is possible that more skills will be added to the database in future.
So, what's the best way to represent a candidate's skills?
[Update] for #zohar, here's a rough first pass at teh schema. Any comments?
You need three tables (at least):
One table for candidates, that will contain all the details such as name, contact information, the cv (or a link to it) and all other relevant details.
One table for skills - that will contain the skill name, and perhaps a short description (if that's relevant)
and one table to connect candidates to skills - candidatesToSkills - that will have a 1 to many relationship with both tables - and a primary key that is the combination of the candidate id and the skill id.
This is the relational way of creating a many to many relationship.
As a bonus, you can also add a column for skill level - beginner, intermediate, skilled, expert etc'.
You might also want to add a table for job openings and another table to connect that to the skills table, so that you can easily find the most suitable candidate for the job based on the required skills. (but please note that skills is not the only match needed - other points to match are geographic location, salary expectations, etc'.)

Improving my Database Design for future scalability

Well, I am working on a project which might involve thousands of users & I don't have much experience in databases especially when it involves relationships between entities.
Let me explain my scenario. First there's an User who can login into our system using his credentials. We have a module in our system, which will enable him to create Projects. So that brings a relationship between User table & Projects table.
Now there's another module, namely Team Creation Module, it does what it says. Out of the list of available members, he can pick who he likes and add them to a team. So there are tables for that Members & Team. Furthermore, a member can be a part of many teams and a team can have many members & a "User" can be member as well.
I have a designed the database myself but I am not sure if it is good or bad one. Moreover, I would really appreciate if someone can point me to good tutorials which shows how to insert or update into tables involving relationships.
Here's my design till now:
Update
After a discussion with someone on IRC, I came up with a revised design. I merged "User" & "Members" table as User is also a Member.
My question still remains the same, Am I on right track?
It's great that you're thinking long-term, but your solution won't work long-term.
This is not the first time this sort of thing has been tried before. Rely on the wisdom of those that have messed up before. Read data modeling pattern books.
Abstract and Normalize. That's how you get to a good long-term solution.
At least read up on The Party Model. A group and individual are actually the same (abstract) thing.
Put actually different things in different tables. An Address and Member don't belong in the same table.
"Am I on the right track" is not a useful question - we have no way of telling, because it depends on where you are headed.
A couple of things:
it's a good idea to name the relation columns after the relationship. For instance, in the first diagram, the "owner" of the project should not be called users_user_id - that's meaningless. Call it "owner_id" or something that meaningfully describes the relationship between the project and members table.
in the second diagram, you appear to have a "many to many" relationship between members and projects in the members table - but there's no efficient way of storing the id of more than one project in the members table. You need to factor that out into a joining table - projects_members, for instance, just like you did with teams_members.
the "teams_members" table has a primary key called tm_id. A purist would tell you this is wrong - the unique identifier for that table should be the combination of member_id and team_id. You don't need another unique identifier - and in fact it's harmful, because you must guarantee uniqueness of the member_id and team_id combination.
As Neil says, you probably want to start reading up on this. I can recommend 'Database Systems: Design, Implementation, and Management' by Coronel et al.

How to design a book library application

I am creating an app for a library. I need to create a database containing details about all the books in the library and the members in the library. I need to maintain a table that connects a person with the books he has read. Each book has a unique id as well the member. I need to track each book taken by the person and recommend books based on his interests. Also i have to track the time required by the person to complete a book. I have only basic knowledge about databases and that too about MySQL only. If I'm right you cannot have multiple values for a field in MySQL. I thought of creating a table for mapping a person with the books he/she has lended. But the problem with such an approach is that the size of the table increases uncontrollably. Is there any other approach that I'm missing that can make my database simpler? I need to frequently search for content from the database. So the table must be as small as possible.
I'm also ready to learn any other language other than MySQL if my requirement is not accomplished by it.
The standard approach would indeed be to create a "join" table that maps people to books. Such a table may have many rows, but each row should only consist of a few columns -- person id, book id, timestamp loaned, timestamp completed.
It is not uncommon to have MySQL tables with millions of rows. Don't worry about that. Make sure to index the person id and book id, and you'll be fine.
You can use this aproach: http://sqlfiddle.com/#!2/33b45/1
You need three tables: books, members, lendings. The code is in the fiddle.

Simple survey database design

I'm creating a survey for visitors of my event.
However it's been a while since I created a database. So I need some help.
I found some solutions but they are way to extensive and that is something I don't need.
Visitors need to stay anonymous but they can leave their email behind (seperate table Emails that isn't linked to anything atm).
They have about 20 questions, some are open, some are one option(radio) and some are multiple options (checkboxes).
The questions need to be reusable.
That's about it.
I just don't know how to go beyond the many-to-many in the diagram you see below.
How do I go from here? An Answers table needs to have a relationship with? The Surveys_have_Questions, or with Questions?
Edit:
As the answer in the following links mentions, most surveys are based upon classic design patterns. Mine is one of those surveys. More info in the link below:
What mysql database tables and relationships would support a Q&A survey with conditional questions?
I would probably model the event of a user taking a survey, perhaps a table called "User_Answer_Session", which has links to the survey and the user; and then "User_Answers", which are tied to the session and the question and include the actual blob of the answer. How exactly I modeled the answers would depend on a few things (mainly how robustly I wanted to be able to look them up). For instance, do I want to be able to index multiple-choice answers for extremely rapid reporting? If so, then you need to model for that. This may include creating a "Question_Options" table, which is a one-to-many between a question and the available options...
This should get you thinking along a good path. :-)
well i dont see reason why you need all these tables ! i think it can be much simpler than that.
surverys
desc VarChar
startDate timestamp
endDate timestamp
isOpen boolean
survery_questions
survery_id int (FK)
question Text
vote_count unsigned INT
user_survery
user_id
survery_id
unique key (user_id_survery_id) #to ensure no duplicate votes
That all :).
when ever a user vote just run
insert into user_survery (user_id,survery_id) VALUES (1,1);
update survery_questions set vote_count = vote_count+1;
when u need to get a survery result
select * from survery_questions where survery_id = X;
etc.

A Beginner Question on database design

this is a follow-up question on my previous one.We junior year students are doing website development for the univeristy as volunteering work.We are using PHP+MySQL technique.
Now I am mainly responsible for the database development using MySQL,but I am a MySQL designer.I am now asking for some hints on writing my first table,to get my hands on it,then I could work well with other tables.
The quesiton is like this,the first thing our website is going to do is to present a Survey to the user to collect their preference on when they want to use the bus service.
and this is where I am going to start my database development.
The User Requirement Document specifies that for the survey,there should be
Customer side:
Survery will be available to customers,with a set of predefined questions and answers and should be easy to fill out
Business side:
Survery info. will be stored,outputed and displayable for analysis.
It doesnt sound too much work,and I dont need to care about any PHP thing,but I am just confused on :should I just creat a single table called " Survery",or two tables "Survey_business" and "Survey_Customer",and how can the database store the info.?
I would be grateful if you guys could give me some help so I can work along,because the first step is always the hardest and most important.
Thanks.
I would use multiple tables. One for the surveys themselves, and another for the questions. Maybe one more for the answer options, if you want to go with multiple-choice questions. Another table for the answers with a record per question per answerer. The complexity escalates as you consider multiple types of answers (choice, fill-in-the-blank single-line, free-form multiline, etc.) and display options (radio button, dropdown list, textbox, yada yada), but for a simple multiple-choice example with a single rendering type, this would work, I think.
Something like:
-- Survey info such as title, publish dates, etc.
create table Surveys
(
survey_id number,
survey_title varchar2(200)
)
-- one record per question, associated with the parent survey
create table Questions
(
question_id number,
survey_id number,
question varchar2(200)
)
-- one record per multiple-choice option in a question
create table Choices
(
choice_id number,
question_id number,
choice varchar2(200)
)
-- one record per question per answerer to keep track of who
-- answered each question
create table Answers
(
answer_id number,
answerer_id number,
choice_id number
)
Then use application code to:
Insert new surveys and questions.
Populate answers as people take the surveys.
Report on the results after the survey is in progress.
You, as the database developer, could work with the web app developer to design the queries that would both populate and retrieve the appropriate data for each task.
only 1 table, you'll change only the way you use the table for each ocasion
customers side insert data into the table
business side read the data and results from the same table
Survey.Customer sounds like a storage function, while Survey.Business sounds like a retrieval function.
The only tables you need are for storage. The retrieval operations will take place using queries and reports of the existing storage tables, so you don't need additional tables for those.
Use a single table only. If you were to use two tables, then anytime you make a change you would in effect have to do everything twice. That's a big pain for maintenance for you and anyone else who comes in to do it in the future.
most of the advice/answers so far are applicable but make certain (unstated!) assumptions about your domain
try to make a logical model of the entities and attributes that are required to capture the requirements, examine the relationships, consider how the data will be used on both sides of the process, and then design the tables. Talk to the users, talk to the people that will be running the reports, talk to whoever is designing the user interface (screens and reports) to get the complete picture.
pay close attention the the reporting requirements, as they often imply additional attributes and entities not extant in the data-entry schema
i think 2 tables needed:
a survey table for storing questions and choices for answer. each survey will be stored in one row with a unique survey id
other table is for storing answers. i think its better to store each customers answer in one row with a survey id and a customer id if necessary.
then you can compute results and store them in a surveyResults view.
Is the data you're presenting as the questions and answers going to be dynamic? Is this a long-term project that's going to have questions swapped in and out? If so, you'll probably want to have the questions and answers in your database as well.
The way I'd do it would be to define your entities and figure out how to design your tables so relationships are straightforward. Sounds to me like you have three entities:
Question
Answer
Completed Survey
Just a sample elaboration of what Steven and Chris has mentioned above.
There are gonna be multiple tables, if there are gonna be multiple surveys, and each survey has a different set of questions, and if same user can take multiple surveys.
Customer Table with CustID as the primary key
Questions Table with a Question ID as the primary key. If a question cannot belong to more than one survey (a N:1 relationship), then can also have Survey ID (of table Survey table mentioned in point 3) as one of the values in the table.
But if a Survey to Question relationship is N:M, then
(SurveryID, QuestionID) would become a composite key for the SurveyTable, else it would just have the SurveyID with the high level details of the survey like description.
UserSurvey table which would contain (USerID, SurveryID, QuestionID, AnswerGiven)
[Note: if same user can take the same survey again and again, either the old survey has to be updated or the repeat attempts have to stored as another rows with some serial number)