SQL and new runtime tables - mysql

I'm designing a database for a website that has to be dynamically modified.
I'll be clearer: there are registered users, who have to complete some surveys (that have to be saved on the same DB). The admin can create and submit to users new surveys. The admin could want to submit a survey just to users who are older than 50yo.
The problem is that I can't find a DB design to solve this problem. All of my ideas are realizable with graph DB, but not with relational DB.
Can you help me to find the right way?
Here is the schema:
member(id, email, password, salt)
member_details(name, surname, region, province, age, job, education)
Now, if the admin wants to submit a new survey to all users, I create (through PHP code) a new table, Survey1:
Survey1(uid, answer1, answer2, ..., answer10)
And it is not so hard. The problem is if she wants to submit a survey just to users over 50yo. How can I achieve this goal?
And how can I handle new users and old surveys? So, if I'm a new user, I should answer to all older surveys, but how can I do it? What kind of relationships do I have to design?

You should never need to dynamically create a new DB table; that implies that there is some structure in the data that your PHP code knows about, but isn't actually stored in your DB.
You need to think about the entities in the system; at its simplest, I can think of 3:
a survey, with its name, when it was created, etc
a survey question, associated to a particular survey, but there could be any number for a survey
a survey answer, associated to a survey question, and the member who answered it
Your current model only really accounts for the last of these, and does so using numbered columns, which is a sure sign you should be thinking about normalisation.
If you create 3 tables, one for each of those entities, the relationships you need should become clearer:
A survey could have a minimum age as a column, or be associated to a set of rows in another table to describe how to select members to ask.
The surveys a member has answered is easy to query from the answers table, or perhaps a table which relates members to surveys, and lists when they answered.
From those two, you can find all the surveys a particular member should answer, and exclude the ones they already have answered.

Related

Store lists/checklist into MySQL database

I want to make a demo application that is able to ask a user if he/she has followed the correct methods to build an item.
I have created a 'checklist' for the user to fill in as he/she builds the item. For example some of the questions could be:
Have you received the correct parts?
Are the parts in good condition?
Are you building a chair?
Do you have the correct specifications for the chair?
...
...
...
And so on...
So these questions have yes/no answers only. My plan was to create a table and call each column by the questions' number. So column 1 will be called '1' and it's the first question. Column 2 will be called '2' and it's the second question and so on.
So this table will be called Chair inspection. I then have another table called Table inspection with its own set of checklist questions.
This data is captured using an android application. The development of the application is done. Just need advice on the database part.
Is this the correct approach to storing the user's inputs?
I advice you have three tables, one for the questions, the other for the users who will be answering those questions and the last one is for the answers, then you establish the relationship between those three tables. That means Many users can answer many questions. Therefore there will be many to many relationship between users and questions. Then there will be relationship between questions and answers and answer with the users who responded to the questions.
I think that way you will be able to avoid redundancy and simplify the process of updating, and retrieving you data.
A normalised schema might be as follows (incomplete, and ignoring 'tables' for the time being) :
inspection
inspection_id* item inspected_by date
inspection_detail
inspection_id* checklist_id* status
* = (component of) PRIMARY KEY

Reusable Questions in MySQL Survey Design

I'm working on a Reusable Survey database design. So the idea is.
A Client has many users, A client has categories which consist of questions. Every User has to answer all questions to complete the Survey. Those answers are stored in the Answers table.
The hard part
Some users are coaches, so a coach can fill in the survey for the user, thus providing a score on what they would answer in the place of the user. So we can later compare what the user answered and what the coach answered for each user. That's not to hard! The following is:
After some months we should be able to let the users redo the surveys, so with new answers to all the still existing questions.
I'm wondering if my db design is allright for this.
I have the feeling that this isn't optimal.
For example the following queries seem difficult with my design
For a given Scan, give me all categories and questions
(because of the many tables in between)
Looking very forward to your responses!
Think about how you are going to want to use this information. Are you going to want to compare users scores to coaches scores to their new scores? I think that is likely. Will they end up taking the survey multiple times if they don't improve enough? Are there going to be questions that do not have integer answers? How are you going to store those results? When they create a new survey are they going to want to reuse some previous questions or answers (like yes/no). How are you going to identify a unique user, names are not unique and autogenerated IDs are unique, but how will you know which John Smith belongs to which of the 12 ids you have?
I would rename the Answer table as SurveyResponse.
To it I would add the datetime of the surveyresponse (so people can
answer it multiple times and you can compare the answers) and a
Survey ID (from the new table in the next suggestion).
I would create a Survey table that stores the questions that belong
to a particular survey.
I would create a new Answer table that just has possible answers and
an ID.
I would create a table called SurveyQuestionAnswer which stores the
allowed answers to the question for each survey (different surveys
might have different possible responses to the same question).

User Point System DB Design Approach

I am looking point system DB Design. My Question is quite similar to the question that I have found here. : - Database design - Approach for storing points for users .
In this system, user earns points when any of this action happens:-
User Register on the website. (i.e Active Entry to the User table)
User Writes Answer of the Other Users Question. (i.e Entry to the
Answer table)
User Answers are rated be other Users. (i.e Entry to Answer Rating
Table for the User )
User Invites Other Users to Join the platform
From the DB Design Side, I have created these two tables:-
Action_Master table, and
User_Action_Point table.
The Action_Master table contains this :- (id, action_name, action_point)
The User_Action_Point table stores the history of each actions, so it look like this:-
(id, action_master_id, action_done, created_by, created_at, updated_by, updated_at, deleted_at)
Now the problem here is the User_Action_Point table, it contains the repeated data of the User Table, Answer Table and Answer_rating Table.
This problem is very well addressed by Jeffrey in the first answer of the linked question. According to his answer we should have to execute Views or Stored Procedure to sum up the points from different tables every time. This approach is awesome because we need not to handle the overhead of data deletion or any other changes that may affect the User Points.
But, is that a good way when we need users points very frequently ? Don't you think this approach can increase the db response time or the loads on the MySQL server ?
or I need to store the aggregated Users points data in some table with the overhead of handling repeated data (i.e if anything get deleted then we also have to minus those points in the point table.)
Please Suggest.

MySQL database model for signups with and without addresses

I've been thinking about this all evening (GMT) but I can't seem to figure out a good solution for this one. Here's the case...
I have to create a signup system which distinguishes 4 kinds of "users":
Individual sign ups (require address info)
Group sign ups (don't require address info)
Group contact (require address info)
Application users (don't require address info)
I really cannot come up with a decent way of modeling this into something that makes sense. I'd greatly appreciate it if you could share your ideas.
Thanks in advance!
Sounds like good case for single table inheritance
Requiring certain data is more a function of your application logic than your database. You can definitely define database columns that don't allow NULL values, but they can be set to "" (empty string) without any errors.
As far as how to structure your database, have two separate tables:
User
UserAddress
When you have a new signup that requires contact info, your application will create records in both tables. When a new signup doesn't require address info, your application will only create a record in the User table.
There are a couple considerations here: first, I like to look at User/Group as a case of a Composite pattern. It clearly meets the requirement: you often have to treat the aggregate and individual versions of the entity interchangeably (as you note). Implementing a composite in a database is not that hard. If you are using an ORM, it is pretty simple (inheritance).
On the other part of the question, you always have the ability to create data structures that are mostly empty. Generally, that's a bad idea. So you can say 'well, in the beginning, we don't have any information about the User so we will just leave all the other fields blank.' A better approach is to try and model the phases as if they were part of an FSM. One of the clearest ways to do this in this particular case is to distinguish between Users, Accounts and some other more domain-specific entity, e.g. Subscriber or Customer. Then, I can come and browse using User, sign up and make an Account, then later when you want address and other personal information, become a subscriber. This would also imply inheritance, and you have the added benefit of being able to have a true representation of the population at any time that doesn't require stupid shenanigans like 'SELECT COUNT(*) WHERE _ not null,' etc.
Here's a suggestion from my end after weighing pro's and con's on this model. As I think the ideal setup is to have all users be a user entity that belong to a group without differentiating groups from individuals (except of course flag a group contact person and creating a link with a groups table) we came up with the alternative to copy the group contact user details to the group members when they group is created.
This way all entities that actually are a person will get their own table.
Could this be a good idea? Awaiting your comments :)
I've decided to go with a construction where group members are separated from the user pool anyway. The group members eventually have no relation with a user since they don't require access to mutating their personal data, that's what a group contact person is for. Eventually I could add a possibility for groups to have multiple contact persons, even distinguishing persons that are or are not allowed to edit any member data.
That's my answer on this one.

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)