database structure for static pages - database

please help me on this one:)
Most of the time I am creating static pages like Contact Us, About Us, FAQs etc
If I want to store some dynamic items in the page, how will my table look like?
Let's say for the FAQ page, I am to store the question and the answer on the database. For the contact page, I will store emails and and some other contact information. Does that mean I have to create a separate table for each?

Often times I've seen people create a table for Meta information. It resembles a key => value relationship, where the first field of a row is the name and the second is the value. So if you were to manage your global contact information in the database, you may have the following rows:
Meta-Data Table
Meta ID | MetaTitle | Meta Value
---------------------------------------------------------
01 | email_address | some.guy#somedomain.com
02 | phone_number | 1.234.567.8901
03 | num_subscribers | 2312
04 | page_styles | background-color:#333333;color:#ffffff
As for your frequently asked questions, you could do that as a table, if you like:
Questions
Question ID | Question | Answer
-------------------------------------------
01 | How tall are you? | Not nearly tall enough.
Or you could simply create a generic 'pages' table:
Pages
Page ID | Page Title | Page Content
--------------------------------------------
01 | FAQs | How tall are you?
| | Not nearly tall enough.
--------------------------------------------
02 | Contact Us | Phone: 1.234.567.8901
| | Email: some.guy#somedomain.com

Based on the information provided, yes - it's quite likely you'll need separate tables.
Tables are just groupings of similar information, and email doesn't relate to questions & answers. With more information about what you're looking to do, and any business rules around it, we can help you with structure if you'd like.

You could just have 1 table which has a page id column and a page content column. The page id being different for each page you want to store in the database. And the page content column can be a text field which contains the HTML you want to display on that page. Then on each page you would query the database passing the parameter for the page content you wanted to display.

Related

How to structure Dynamodb correctly to have nested or linked properties?

I am getting started with Dynamodb and I am trying to figure out what is the correct way to structure the following:
I have a user, and each user can have multiple pictures (s3 links and some metadata), with no limit to the amount.
Whenever I am calling for a user I would retrieve all their pictures, there would be no reads on a single picture, and each time a user uploads a picture, I need to store it for the user.
In Mongodb I would have created an array called pictures holding objects with each picture's data. Is this also the correct approach in Dynamodb?
Here is how you can do with dynamodb
| pk | sk |
| user1 | metadata | age:24 | name: Jon| ...
| user1 | picture#1234#id1 | url:abc.com/xyz.jpeg | ... some other metadata
| user1 | picture#2456#id2 | url:abc.com/xyz.jpeg | ... some other metadata
| user1 | picture#4567#id3 | url:abc.com/xyz.jpeg | ... some other metadata
where 1234, 2456 may represent epoch time uploading the picture.
Now you can do queries like
get me all the pictures in chronological order.
Select * from table where pk=user1 and sk starts with picture#
get me all the pictures uploaded b/w or after certain date.
Select * from table where pk=user1 and sk starts with picture# and sk>picture#1234
Get me user details
Select from table where pk=user1 and sk=metadata
This will make sure few things
No race condition/lock while uploading the picture
you can decide how many images you want to fetch, And you will read only what you need, instead of loading all of them and then filtering.

CakePHP 2.9 converting CSV string to HABTM data

I am trying to convert a large database (~3m rows) that contains the following data set titled "Posts":
+-------|---------------|-----------------------+
| id | name | tags |
|-------|---------------------------------------|
| 1 | post title | tag_a, tag_b |
| 2 | another title | tag_b, tag_e, tag_j |
+-------|---------------|-----------------------+
I also have an empty "tags" table with the headings id, title and a "posts_tags" table with the headings id, post_id, tag_id
Post <-- Habtm --> Tag
My question:
I would like to know the most efficient (preferred but not required cake way) of populating the "tags" table and the "posts_tags" habtm table while keeping the tags table free from duplicates?
Many Thanks SO Team!
I have no time to write code right now.
You could get all posts (I recommend you paginate your result) and for each post, you get its tags and explode it by comma.
Then you create an HABTM array data using the tags and the currently post, and finally you save your data.

Database Design - Drop Down Input Box Issue

I'm trying to create a friendship site. The issue I'm having is when a user joins a website they have to fill out a form. This form has many fixed drop down items the user must fill out. Here is an example of one of the drop downs.
Drop Down (Favorite Pets)
Items in Favorite Pets
1. Dog
2. Cat
3. Bird
4. Hampster
What is the best way to store this info in a database. Right now the profile table has a column for each fixed drop down. Is this correct database design. See Example:
User ID | Age | Country | Favorite Pet | Favorite Season
--------------------------------------------------------------
1 | 29 | United States | Bird | Summer
Is this the correct database design? right now I have probably 30 + columns. Most of the columns are fixed because they are drop down and the user has to pick one of the options.
Whats the correct approach to this problem?
p.s. I also thought about creating a table for each drop down but this would really complex the queries and lead to lots of tables.
Another approach
Profile table
ID | username | age
-------------------
1 | jason | 27
profileDropDown table:
ID | userID | dropdownID
------------------------
1 | 1 | 2
2 | 1 | 7
Drop Down table:
ID | dropdown | option
---------------------
1 | pet | bird
2 | pet | cat
3 | pet | dog
4 | pet | Hampster
5 | season | Winter
6 | Season | Summer
7 | Season | Fall
8 | Season | spring
"Best way to approach" or "correct way" will open up a lot of discussion here, which risks this question being closed. I would recommend creating a drop down table that has a column called "TYPE" or "NAME". You would then put a unique identifier of the drop down in that column to identify that set. Then have another column called "VALUE" that holds the drop down value.
For example:
ID | TYPE | VALUE
1 | PET | BIRD
2 | PET | DOG
3 | PET | FISH
4 | SEASON | FALL
5 | SEASON | WINTER
6 | SEASON | SPRING
7 | SEASON | SUMMER
Then to get your PET drop down, you just select all from this table where type = 'PET'
Will the set of questions (dropdowns) to be asked every user ever be changed? Will you (or your successor) ever need to add or remove questions over time? If no, then a table for users with one column per question is fine, but if yes, it gets complex.
Database purists would require two tables for each question:
One table containing a list of all valid answers for that question
One table containing the many to many relation between user and answer to “this” question
If a new question is added, create new tables; if a question is removed, drop those tables (and, of course, adjust all your code. Ugh.) This would work, but it's hardly efficient.
If, as seems likely, all the questions and answer sets are similar, then a three-table model suggests itself:
A table with one row per question (QuestionId, QuestionText)
A table with one row for each answer for each Question (QuestionId, AnswerId, AnswerText)
A table with one row for each user-answered question (UserId, QuestionId, AnswerId)
Adding and removing questions is straightforward, as is identifying skipped or unanswered questions (such as, if you add a new question a month after going live).
As with most everything, there’s a whole lot of “it depends” behind this, most of which depends on what you want your system to do.

Friendship Website Database Design

I'm trying to create a database for a frienship website I'm building. I want to store multiple attributes about the user such as gender, education, pets etc.
Solution #1 - User table:
id | age | birth day | City | Gender | Education | fav Pet | fav hobbie. . .
--------------------------------------------------------------------------
0 | 38 | 1985 | New York | Female | University | Dog | Ping Pong
The problem I'm having is the list of attributes goes on and on and right now my user table has 20 something columns.
I feel I could normalize this by creating another table for each attribute see below. However this would create many joins and I'm still left with a lot of columns in the user table.
Solution #2 - User table:
id | age | birth day | City | Gender | Education | fav Pet | fav hobbies
--------------------------------------------------------------------------
0 | 38 | 1985 | New York | 0 | 0 | 0 | 0
Pets table:
id | Pet Type
---------------
0 | Dog
Anyone have any ideas how to approach this problem it feels like both answers are wrong. What is the proper table design for this database?
There is more to this than meets the eye: First of all - if you have tons of attributes, many of which will likely be null for any specific row, and with a very dynamic selection of attributes (i.e. new attributes will appear quite frequently during the code's lifecycle), you might want to ask yourself, whether a RDBMS is the best way to materialize this ... essentially non-schema. Maybe a document store would be a better fit?
If you do want to stay in the RDBMS world, the canonical answer is to have either one or one-per-datatype property table plus a table of properties:
Users.id | .name | .birthdate | .Gender | .someotherfixedattribute
----------------------------------------------------------
1743 | Me. | 01/01/1970 | M | indeed
Propertytpes.id | .name
------------------------
234 | pet
235 | hobby
Poperties.uid | .pid | .content
-----------------------------
1743 | 234 | Husky dog
You have a comment and an answer that recommend (or at least suggest) and Entity-Attribute-Value (EAV) model.
There is nothing wrong with using EAV if your attributes need to be dynamic, and your system needs to allow adding new attributes post-deployment.
That said, if your columns and relationships are all known up front, and they don't need to be dynamic, you are much better off creating an explicit model. It will (generally) perform better and will be much easier to maintain.
Instead of a wide table with a field per attribute, or many attribute tables, you could make a skinny table with many rows, something like:
Attributes (id,user_id,attribute_type,attribute_value)
Ultimately the best solution depends greatly on how the data will be used. People can only have one DOB, but maybe you want to allow for multiple addresses (billing/mailing/etc.), so addresses might deserve a separate table.

Database relationships - 1:1 but not always?

Apologies for the fairly unhelpful title, if you have a better suggestion please feel free to edit it.
I'm using CakePHP and the bake functionality (I don't need to bake however).
What's the best way of achieving the following:
table schema:
table ranges
id | name | description
table images
id | range_id | picture
table info (here i am confused)
id | range_id | height | width | colour
Basically, one range may have many images (1:Many). I can show this fine.
Now, each range will have an entry in the info table (1:1) and some attributes about the range such as height, colour, width. But not always...
Let's say I have a range foo. foo has five images that all have the same height, width and colour. However, foo has one image that is a different size and a different colour.
When the attributes differ, I need to show this information with the respective image, rather than the ranges default information. So this image will need it's own entry in the info table.
Does this even make sense? Or am I going about this entirely the wrong way.
My application, in brief:
(If it helps, think of "range" as a product)
User selects a range
User views images in the range
User can click an image, and the information from info pops up about that range.
Some images have different attributes, but still belong to the same range.
How can I make this distinction and store it appropriately?
Please let me know if I can clarify further. Thank you.
I've needed to do this on occasion where a parent entity has a value that can get "overridden" by a child entity.
There are a couple of approaches you can take the structure being the easiest part.
consider the following structure
table ranges
id | name | description | default_info_id
table images
id | range_id | picture | info_id
table info
id | height | width | colour
When does image.info_id have a value? There are two choices
Populate the image.info_id with the default_info_id from the parent. The user can then override it on the image
Pros
You never need to look at the Range to figure out what the info is on the image
Cons
you need to decide what to do when the range.default_info_id changes. does it effect the images or is it just for future
Only Populate the images.info_id when its different than the parent.
Pros
If the parents.default_info_id changes when images.info_id is null it will automatically change as well
Cons
you need to decide what to do when the range.default_info_id changes. Do you need to now null out any images.info_id that are now the same as the parent?
You need to look at the rages table to figure out what the info_id is on the images when its null.
You can have several varieties of the above data structures but you'll still need to figure when to populate what. Here are two others you could consider that are valid (but less optimal in my opinion)
Info has an FK to both tables but one is always null
table ranges
id | name | description
table images
id | range_id | picture
table info
id | range_id | image_id | height | width | colour
No Info Table at all
table ranges
id | name | description | default_height | default_width | default_colour
table images
id | range_id | picture | height | width | colour

Resources