0

Let me try to explain my situation for the application what I am working on,

I have close to 7 categories, lets say A,B,C,D,E,F and G.These categories dont have any table in DB side.Now User selects some categories out of these 7 , lets say C,so in category C, I have another bunch of subcategories, namely C1,C2,C3 to C30.Lets assume now that users Selects C2, for C2 subcategories I have table in the database which gets inserted once user enters all the data via front end.Now C2 table has got 8 columns namely c2t1id,c2t2....c2t8. It has autoincrement id column as well which gets autoincrements for every insert to that table and its primary key for that table.

Now my problem, is that I need to show the users all inserts they have across the application in all the tables.User can do insert in all 7 categories and each category has subcategory upt0 30 and as per existing design this becomes close to 210 tables.

Now my login table is structured with id/name/pw.

Now looking at my design from the prospective of db side, I am starting to get the sense that this design is somewhat flawed and I am starting to get the sense that just to retreive 5 records of the user, I need to search 200+ table with long mulititable select join ?

I need some hints as how I should be proceeding further on this.I am ready to redesign in case if it required.

Jamie
  • 816
  • 4
  • 6
Kiran Badi
  • 501
  • 2
  • 9
  • 24

4 Answers4

1

It definitely sounds like you need to examine your design before proceeding further.

Rather than talking in generalities, talk in specifics. It's hard for people to recommend a database design when they don't know the details of the data.

So, tell us specifically what the data is.

EDIT:

Given what you've told us about your data, it'd look something like this:

USER
----------------------
ID (PK) INTEGER AUTOINCREMENT NOT NULL
EMAIL (PK) VARCHAR(1000) NOT NULL
FIRST_NAME VARCHAR(50) NOT NULL
LAST_NAME  VARCHAR(50) NOT NULL
ENCRYPTED_PASSWORD ....etc


POST
--------------
ID (PK) INTEGER AUTOINCREMENT NOT NULL
USER (FK) INTEGER NOT NULL
CONTENT TEXT NOT NULL
DATE_POSTED TIMESTAMP NOT NULL
DATE_EDITED DATETIME NOT NULL


POST_CATEGORIES
--------------------
ID (PK) INTEGER AUTOINCREMENT NOT NULL
CATEGORY_ID (FK) INTEGER NOT NULL
POST_ID (FK) INTEGER NOT NULL

CATEGORY (hierarchal table)
------------------------------
ID (PK) INTEGER AUTOINCREMENT NOT NULL
PARENT_ID INTEGER
CATEGORY_NAME VARCHAR(200) NOT NULL

Note that the CATEGORY table is using a simple agency list model. Other types of models are possible. See the excellent Managing Hierarchal Data in MySQL article for more details.

With this design, getting a list of user posts would be a matter of:

select * from POSTS where USER = (select ID from USER where FIRST_NAME = 'John' and LAST_NAME = 'Doe');

If you want to add on the categories, you'd join the POST_CATEGORIES and CATEGORY tables too. Obviously this is a simplified example, but hopefully you can see how this design would support hundreds or thousands of categories with hundreds of thousands or millions of posts in just a handful of tables.

wadesworld
  • 13,535
  • 14
  • 60
  • 93
  • hi wadesworlds,subcategory structure is something like,{cid: INT}, {ctitle: VARCHAR}, {cname: VARCHAR}, {caddr: VARCHAR}, {cph: DOUBLE}, {coffs: VARCHAR}, {ctmaps: VARCHAR}, {ctimg: VARCHAR}, {ctdatetime: DATETIME}.These are subcategory column details for Category C.The other categories might have more than 8 columns in all.(I have start working on those modules yet,but I am sure it will more columns than this one).Data what I am inserting is pretty simple ,its form with around 7 fields and files are stored in local disk with path going into the db.So there is no blob or clob involved anywhere – Kiran Badi Jun 10 '12 at 17:01
  • I don't mean tell us about the datatypes. I mean tell us what the application does. Is it an order tracking system? Is it a role-playing game? Is it sequencing genetics? Then tell us what the data is: "each player can be one of 8 classes. Each class can have up to 20 abilities," etc...in other words, describe what you're trying to store. – wadesworld Jun 10 '12 at 19:42
  • Hi wadesworld, closest example I can think of is ebay classified site or craglist.if you look at the design of craglist or ebay classified, my requirements looks almost similar.you have main category , then you go subcategory and then you post some details to subcategory(to post you require login), your post details gets inserted to db.Good so far till here.Now lets move user account details, he needs to see how many posts he has done in month/day etc, so obviously you need track his posts, and this is want I my requirement is.How should I track this. – Kiran Badi Jun 10 '12 at 20:35
  • Hi Wadesworld, thanks I got the hint as how I should proceed now.I see the gap in my design now.There is not clear cut relationship between parent and child.Its something like parent is hardcoded(via ui) and client does inserts on child tables. and when I need to pull data from child tables, there is not relationship between userid/parent tables/child tables and thats the reason why I was blank.So what I understand from all these discussion here is that, I need to relate parent to the child and for every insert in child table, need to have parent id and user id associated with this. – Kiran Badi Jun 11 '12 at 15:18
  • This should resolve my design flaws.But the challenge here is that I dont see that this will reduce the requirements for the number of tables for children.Here categories is parent and subcategories are children.Since each children will have different number of columns associated with them(think unqiue customisation for each subcategories),so obviously I fear that tables will go upto 200+ making the kind of challenge for some of the functionality like doing global search. – Kiran Badi Jun 11 '12 at 15:23
  • Second option which I can use reduce the number of tables will be to increaase the number of columns in the existing tables and fit in all those unqiue customisation of subcategories,however this approach will lead me to have many null values in the table and will cause to drastic change in the server side code to handle these null values successfully. Overall I think I got the hint as how I should be proceeding with this.Many thanks – Kiran Badi Jun 11 '12 at 15:25
0

Yup, that design is a loser. 210 tables? Think again. Stop thinking in terms of tables and columns and express it as the problem you're trying to solve. Maybe a relational database isn't appropriate here.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Thanks Duffymo,but again I dont think without DB , I can built the applicaton.I think db is required.What was thinking was creating one more column for subcategory table which will somehow relate user with subcategory and then pull data from subcategory based on that column.But using this approach also I have search close to 200 tables.Other than this I am blank as how to optimise the design. – Kiran Badi Jun 10 '12 at 16:58
  • 1
    I think what @duffymo is hinting towards is a NO-SQL style database. – bumperbox Jun 10 '12 at 23:46
  • Not necessarily. The first step is to identify the problem in human, business, terms. That way one can start thinking about the db implementation that fits that. If you have to think db first that's fine. You just need to accept that you need to change that approach. – Michael Durrant Jun 11 '12 at 00:20
  • No I did not think DB first,I implemented most of the functionaities with simple table creation and then building client and server side code.Now for few functionailty, like showing users past activity, and doing global search , I realised that tables are not related to each other and they were sitting in isolation.This made me realise that something was wrong, and that prompted me to check this here.This is my own site,so there are some elements in design which I am experimenting with and some are regular stuff we often. – Kiran Badi Jun 11 '12 at 15:36
  • Not sure if this relates to your suggestion,but just to give you some background info. – Kiran Badi Jun 11 '12 at 15:36
0

A hierarchical structure with a table per node is not the usual answer - I'd suggest checking out the answers to this question to see if any of the advice applies to your problem.

Community
  • 1
  • 1
Jamie
  • 816
  • 4
  • 6
  • No its not similar to mine.I dont have 3 to 4 level relationship.Mine is simple, I have categories which is parent and then each parent will have many subcategories(say 30 childrens with different columns in it), users are allowed to do inserts/update/search on childrens.A users can do search for the children based on the parent.In all I have around 8 parents and each parent will have 30 childrens min.So it becomes one to many relationship for parent child. – Kiran Badi Jun 11 '12 at 15:55
0

Based on your comments/explanation to @wadesworld Here is a simple design that might point you in the right direction

I have kept the structure as simple as possible, you can all more columns/details to suit your application, and I have shown a few samples of how you can query your data.

TABLE: USERS
ID | USERNAME | PASSWORD

TABLE: CATEGORIES
ID | CATEGORY_ID | NAME

TABLE: POSTS
ID | CATEGORY_ID | DESCRIPTION | USER_ID



// list all top level categories (We use NULL in categories.category_id to indicate it has no parents)
SELECT * FROM categories WHERE category_id IS NULL;

// list all sub categories for category_id = 2
SELECT * FROM categories WHERE category_id=2;

// list parent and child categories, for use in a html select
SELECT parent.id, parent.name, child.id, child.name
  FROM categories AS parent
  JOIN categories AS child ON child.category_id=parent.id
  WHERE parent.category_id IS NULL

// insert a post into category_id=2 for user_id = 1
INSERT INTO posts (category_id, description, user_id)
  VALUES ('2', 'test post', 1);

// select all posts by user with username=tom
SELECT * FROM users
 JOIN posts ON posts.user_id=users.id
 JOIN categories ON categories.id=posts.category_id
 WHERE users.username='tom';

 // count the number of posts made by tom in each category
 SELECT categories.name, COUNT(*)
   FROM users
   JOIN posts ON posts.user_id=users.id
   JOIN categories ON categories.id=posts.category_id
   WHERE users.username='tom';
   GROUP BY categories.name
bumperbox
  • 10,166
  • 6
  • 43
  • 66
  • Thanks Bumperbox, I got the hint from you as well and Wadesworld.I will keep this thread going on for some more days as I try these changes for new module. – Kiran Badi Jun 11 '12 at 15:28