Database design for voting - database

I am implementing a voting feature to allow users to vote for their favourite images. They are able to vote for only 3 images. Nothing more or less. Therefore, I am using checkboxes to do validation for it. I need to store these votes in my database.
Here is what i have so far :
|voteID | name| emailAddress| ICNo |imageID
(where imageID is a foreign key to the Images table)
I'm still learning about database systems and I feel like this isn't a good database design considering some of the fields like email address and IC Number have to be repeated.
For example,
|voteID | name| emailAddress | ICNo | imageID
1 BG email#example.com G822A28A 10
2 BG email#example.com G822A28A 11
3 BG email#example.com G822A28A 12
4 MO email2#example.com G111283Z 10

You have three "things" in your system - images, people, and votes.
An image can have multiple votes (from different people), and a person can have multiple votes (for different images).
One way to represent this in a diagram is as follows:
So you store information about a person in one place (the Person table), about Images in one place (the Images table), and Votes in one place. The "chicken feet" relationships between them show that one person can have many votes, and one image can have many votes. ("Many" meaning "more than one").

Related

How to edit Relationship properties to only use part of the CDM Identifier in LDM?

I'm creating a conceptual data model for a simplified web store using Power Designer.
I'm having trouble specifying the relation between an Order and a Receipt. I would like a receipt to only have a part of the order's identifier in its primary key in the logical model (more specifically, only order_id). I am unable to achieve this by tweaking the relationship properties (see the screenshots bellow; the problematic relationship is marked with a green arrow).
Should I simply omit the relation in the conceptual model?
Conceptual data model
Logical data model
EDIT
If perhaps it wasn't clear how I envisioned my tables…
User
username
password
mail
first_name
last_name
address
hacker123
greenGrass
david.norton#gmail.com
David
Norton
West Shire 40, 1240 Neverland
musicman100
SuperPassword
john.stewart#gmail.com
John
Stewart
Strange Alley 50, 1250 Outer Space
Product
product_id
name
description
price_per_unit
unit_of_measure
supply
1
Tooth Brush 100
NULL
5.99
piece
200
2
Super Paste 200
For sparkling smiles
7.99
piece
50
Order
order_id
username
product_id
amount
50
hacker123
1
2
50
hacker123
2
1
51
musicman100
1
5
Receipt
receipt_id
order_id
12
50
13
51
EDIT #2
I just realised that I should probably break up Order into two tables! One to track which products are on a particular order, and another to track who placed the order.
Perhaps I could even split the Order table into 3 parts
Order(order_id, order_time)
ProductsPerOrder(order_id, product_id, amount)
OrdersPlaced(order_id, username)
You have a contradiction... One part says that Order is identified by User+Product+Order; the other says that Order has its own identifier order_id.
I guess the second one is correct, with the usual design that Order has an id.
And you need to change the relationships in the CDM, between Order, and User/Product, to uncheck the Dependent property. These links are just mandatory, not dependent (which would mean that Order is defined relatively to User+Product).
p.s. the same holds for Receipt, which has its own identifier.
You can edit the relationship in the logical model!
If you click on a relationship, a Relationship properties dialog appears. There's a tab called Joins. This is where you can specify which columns to refer to with the relationship.

Is it good practice to assign ranges to userid?

I'm building a database schema for users of my app, and I am thinking of setting the userid value according to user type. So,
buyers: 10001 to 19999
sellers: 20001 to 29999
shippers: 30001 to 39999
Next, I assign unique email addresses to the userid:
Login_table
Email.......password.......userid
aaaaa#yy.com....... password.......10005 ---> this email belong to user 10005 (a buyer)
bbbbb#yy.com.......password.......20008 ---> this email belongs to user 20008 (a seller)
ccccc#yy.com.......password.......30187 ---> this email belongs to user 30187 (a shipper)
I then have 3 tables for buyers, sellers, and shippers because each may have different attributes:
buyer_table
buyerid.......name....... mother
10005....... John....... Mary
10006 ....... Chris....... Nancy
seller_table
sellerid....... name....... pet
20008 ....... Adam....... Dog
20018 ....... Tony ....... cat
shipper_table
shipperid....... name....... car
30187....... George....... GMC
30188 ....... Larry ....... Honda
The advantage here is that I have a single login_table for all user types. I do not want to have 3 login tables for each type. Based on the userid value I know what type of user it is. Keeping three tables for each user (buyer_table, seller_table, and shipper_table) is good for making the schema more understandable, in addition to being able to assign different attributes to each user type.
Sounds good? Maybe.
However, I have a problem in that the login_table refers to “userid” while the three user tables each has a different id name for the user, so in the buyer_table I have buyerid as primary key, in the seller_table it is sellerid as primary key, and finally in the shipper_table, the shipperid is the primary key.
How can I link these three primary keys to the login_table? The login_table has userid as a foreign key to one of those three tables, but it is called “userid”, not buyerid, or sellerid, or shipperid!
1) Is it a good idea to classify the userid value according to ranges?
2) If so, how can I resolve the PK-FK issue as described above?
3) Am I off completely?
Having ranges of values for different kinds of similar objects is not bad. If you feel like doing so, you could use sequences wich support value ranges. This way, you could have a buyer sequence wich goes from 0-1000, a seller one from 1001 to 2000 and so on. That would also help you keeping track of the increasing index of the different kinds!

Many to Many Database Relationship Design - to enable Word Clouds

I'm relatively new to database design and struggling to introduce a many-to-many relationship in a SSAS Tabular model.
I have some 'WordGroup' performance data in one table, like so;
WordGroup | IndexedVolume
Dining | 1,000
Sports | 2,000
Movies | 1,600
... and so on
Then I have 'Words' contained within these 'WordGroups' sitting in another category table, like so;
WordGroup | Word
Dining | Restaurant
Dining | Food
Dining | Dinner
Sports | Football
Sports | Basketball
... and so on
I can't see Performance data (IndexedVolume) by 'Word' detail - only by the 'WordGroup' that it is contained within. For example above, I can't look at 'Football' IndexedVolume on it's own, I can only choose the 'Sports' WordGroup that contains Football.
However, when analysing by 'WordGroup' I would still like users to understand what 'Words' are included (ideally in a Word Cloud Visualisation). Therefore, I wanted to develop a relationship between these two tables, so when someone chooses a Word Group (or multiple) we can return the Words that are contained within the Word Group(s) - i.e. below.
User selects Dining WordGroup
<<<Word Cloud or Flat Table would show Words below>>>
Restaurant
Food
Dinner
I looked at Concatenate / Strings etc, but was deterred as the detail here is much more complex and each WordGroup may contain 10+ Words, with translations.
Any advice would be greatly appreciated!
If analizing by WordGroup is an obligatory requirement, you sholud use these tables:
The many-to-many aplies beacuse your words may be conected to one or more groups, e.g. tree is conected to enviroment, forest, etc.
and obviously one word_group is conected to many words.
To see performance data by Word use :
select w.idword , w.name, sum(wg.index_volume)
from word w
left join word_group_has_word wgw
on w.idword=wgw.word_id
left join word_group wg
on wg.idword_group=wgw.word_group_id
group by w.idword
So you will see the sum of all the index volume of all the group_words conected to the words. ANd if you wanna see the words conected to the word groups use:
select distinct w.idword , w.name
from word w
left join word_group_has_word wgw
on w.idword=wgw.word_id
where wgw.word_group_id in [listWordGroupsId]

Correct Database Architecture

I don't know how to design my mysql webdatabase for a shop.
The scenario is for a site selling guided tours.
Each tour can be either a Private, a Semi-Private or a Group Tour. The price per person changes per tour type. BUT ALSO for the Private tours, the price per person varies depending on the number of persons. However it varies by different amounts depending on tour. How would i create a 'Tour/Product' record?
e.g. Let's say:
Tour of Vatican (tour has various bits of data - name, description, meeting point, duration, etc). Semi-Private tour costs 50 euro per person. Group tour costs 45 euro per person. Private tour costs (140 euro for 1-2 people), or 180 euro for 3 people, or 200 euros for 4 people, or 225 euros for 5 people or 240 euro for 6 people or for 7 people or more it costs 43 euro per person.
HOWEVER for the Tour of Coliseum (tour has same bits of data - name, description, meeting point, duration, etc), Semi Private costs 40 per person. Group costs 25 per person. Private tour costs (100 euro for 1-2 people), or 135 euro for 3 people, or 160 euros for 4 people, or 175 euros for 5 people or 180 euro for 6 people or for 7 people or more it costs 25 euro per person.
How would i structure the data in the database - 2 tables? 3 tables?
Totally confused....
Thanks
Tom
From what I understand from your post, the price alters depending on three different things:
The tour: the price for the Tour of Vatican is not similar with the price for the Tour of Colloseum.
The type of the tour: Private, a Semi-Private or a Group Tour.
The number of persons on the tour.
Since there is no exact (constant) price per person on any of the given options, I would go for a three tables approach.
The digaram is detailed in the below picture and works under the following assumptions:
There are three tables: Tour (containing the description for each individual tour); TourPriceOptions (containing the individual price options records) and TourType (which at all times, will contain just three records: Private, Semi-Private and Group Tour);
There are just two assumptions that you have to do:
A tour can have multiple price options (1 to many relationship)
An price option can have just one single tour type (1 to 1 relationship)
How to code this up:
Whenever the administrator of the store creates another tour in the backend of the store, he should be able to add multiple price options. In order to do this you will need to:
Create a new tour: a function which inserts in to the database a new entry in the tour table.
Get the id of the recently created tour: if there is only one person adding information at any given time, then there is a good bet to write a function that returns the id of the latest added tour.
Add pricing options based on the id_tour: insert a new price option based on the id_tour variable. Remember to assign a tour_type from one of the already predefined categories.
Whenever you want to return these values, just write a query that allows you to retrieve information based on the tour the user is currently browsing.
Additional things to research: Dynamic Forms - They will help you when you don't know how many price options an admin might want to add for a specific tour

relational database design for multidimensional matrix questions

I am designing a relational DB for an online survey.
However, I am not sure what is the best relational database design for storing multidimensional matrix questions.
Let's say, I have the following question (sorry, it does not allow me to insert HTML table):
What was your experience of...
----------| Not friendly| (2) |Very friendly|Length of stay|Visited in the last year?|
Sydney |radio button | rb | rb | drop down | check box |
--------------------------------------------------------------------------------------
New York | rb | rb | rb | drop down | check box |
--------------------------------------------------------------------------------------
London | rb | rb | rb | drop down | check box |
--------------------------------------------------------------------------------------
Do you think I should do something along the following lines or is there a better way?
To hold all the question:
Question
questionID
question
QuestionMatrix2d
matrix2dID
questionID
subquestionID
subquestion
QuestionMatrix
questionID
matrix2dID
question_parentID
And to hold all the responses:
QuestionResponse
questionID
response_code
QuestionMatrix2dResponse
questionID
subquestionID
response_code
Thank you for your help.
I disagree with ryan1234. This totally is a relational problem, and there is very little reason not to put it into a database.
I have to do a bit of guesswork though, in what you're trying to achieve here. You have an online survey, so I assume it will be used by more than one person. Your database will need to acommodate for that by having a session or user table, I'll go with the latter since it is more clear to read.
Secondly, you have a list of locations (Sidney, New York, London). I assume this list can either change over time or even from one questionaire to the next.
Then you have a set of questions. You don't explicitly state that these would be variable or fixed. Since you designed a set of tables for that, I assume it's supposed to be variable. Please note that your questions are not a matrix, but a list. Even if they are hierarchical, they still do not compose a matrix.
Last but not least you've got answers to those questions.
Lets create a users table:
user_id user_name
1 me
2 somebody else
Second table is as simple: locations
location_id location_name
1 Sidney
2 New York
3 London
Third table is a bit more complicated - and to be honest: just plain ugly. But this is what you get if you design a database in a database, and the alternatives (using DDL or storing that information in XML/JSON or even outside the database) are not pretty either. If there is a hierarchical question (your examples don't show them), you could add a "parent_question_id" column.
question_id question_text question_type question_type_info
1 How do you rate RADIO 0 to 5
2 Length of stay COMBOBOX 1 day, 2 days, whatever
3 Visited last year CHECKBOX
Finally you need a fourth table to store all the answers
user_id location_id question_id value
1 1 1 2 <-- value here means "rating of 2"
1 1 2 5 <-- value here means "5 days"
1 1 3 1 <-- value here means "yes, visited last year"
Yep. ugly as well. If you had a fixed list of questions I could provide you with a pretty database :)
Edit: Answering to your comments: To link your questions to a survey, you'll need a few more tables surveys defining which questions for which locations are going to be asked. The following database layout lets you specify a list of locations and a list of questions asked as well as a survey name.
Table surveys:
survey_id survey_name
1 Spring 2013 London Travel Survey
2 Spring 2013 Northern Hemisphere Short Survey
Table survey_questions:
survey_id question_id
1 1
1 2
1 3
2 1
Table survey_locations:
survey_id location_id
1 1
2 1
2 2
The contents I put in here gives you two surveys. Survey #1 will ask all three questions just on one location: 'London'. Survey #2 will just ask one question on both London and New York. If you want to ask different questions on different locations your table layout will have to accommodate for that, but such a system won't fit into your original table-like layout.
Having done things similar to this, I would recommend considering not turning this into a relational problem. What if you have objects and just serialize them to something like JSON and store that?
Doing this relationally you'll end up spending quite a bit of time making tables and wiring together complex drawing code in your application to make sure the questions/answers draw in the right order etc.
Otherwise I think you can make your approach work. There is no silver bullet for designing survey stuff in an RDBMS.

Resources