Question

I want to build up a database where there will be about 400 strings. I want to make the database searchable.

The structure of the database will be like:

Brand | model |additional products | price | search words | (this is 1 string, there will about 400 strings)

There will be between 2 and 50 search words on each string. The search are done by clicking a checkbox and the marked checkboxes words will be searched for in the database.

My question is how is the best way to index all the search words? I’m thinking of 2 ways:

  1. In the field search words, all searchable words will be displayed like: 1GB RAM, 512GB RAM, ATA, SATA… and so on for each string. This means that ALL words will be in the same raw on a specific string separated by “,”.

  2. Each search word will have its own row like: | search words 1| search words 2| search words 3 | search 4 words 5|….. and so on. In |search words 1| the word 1GB RAM will be. In | search words 2| the word 512GB RAM will be and so on… This means in a string maybe half the search words row will be filled with a search word.

In option 2 there will be more than 50 rows in the database and all search words in different column (1 in each column for each product). In option 1 there will be 1 row with all words in the same column for each product.

Or is there a better way to do this?

Was it helpful?

Solution 2

Storing your search terms in never-ending additional columns is counter-intuitive to database "normalization". Storing everything in one column is usually the last option since it is much easier to break down search terms if you use multiple columns.

Make a separate table and join your original table to this table. Your structure would look something like this:

Original table

enter image description here

New table

enter image description here

I added a primary key column to your original table. This will make the JOIN easier. Use the following statement to join the two tables:

SELECT original_table.*
FROM original_table AS ABB2
    JOIN new_table AS ABB1 ON ABB1.product_id = ABB2.id
WHERE search_word = "your search term"

The "search_word" column in the new table are the terms associated with each of your entries in your original table.

You can add "%" wildcards to your WHERE statement if you'd want fuzzy (return all results that contain your search term) search enabled.

OTHER TIPS

Even though another answer was accepted... I explained this idea a little more because I feel that it meets "best practices" and allows you to associate more than one word with one item while not repeating data.

You should end up with three tables:

item:        item_id | Brand | model |additional products | price 

word:        word_id | word 

item_word:   item_word_id | item_id | word_id 

the data would look like:

Item:

item_id   brand     model        additional_products   price 
1         nokia     g5                                   100 
2         toshiba   satellite                           1000 

word:

word_id   word 
1         1 GB
2         ATA
3         SATA
4         512BG RAM 

item_word:

item_word_id    itwm_id     word_id
1               1           1
2               1           2
3               2           3
4               2           4

so that nokia had these words: 1 GB, ATA and toshiba had these words: SATA, 512BG RAM. (I realize this doesn't make much sense, it's just an example)


then query it like..

select  item.*, word 

from    item 

        join item_word on item.item_id = item_word.item_id

        join word on item_word.word_id = word.word_id 

and filter it like...

select  item.*, word 

from    item 

        join item_word on item.item_id = item_word.item_id

        join word on item_word.word_id = word.word_id 

 where  word in ('1GB RAM', '512GB RAM', 'ATA')

to see what is the most relevant result you could even try...

select  item.item_id, item.brand, item.model, count(*) as word_count

from    item 

        join item_word on item.item_id = item_word.item_id

        join word on item_word.word_id = word.word_id 

 where  word in ('1GB RAM', '512GB RAM', 'ATA')

 group  by item.item_id, item.brand, item.model

 order  by count(*) desc 

for something that matches all the words provided, you would use...

select  item.item_id, item.brand, item.model, count(*) as word_count

from    item 

        join item_word on item.item_id = item_word.item_id

        join word on item_word.word_id = word.word_id 

 where  word in ('1GB RAM', 'ATA')

 group  by item.item_id, item.brand, item.model

 having count(*)=2

where 3 is the number of words in your in statement... word in ('1GB RAM', 'ATA'). in this case it was 2.


if you just do...

item:  Brand | model |additional products | price | long_word_string

then you have to do...

 select  * 
 from    item 
 where   long_word_string like '1GB RAM' or word like 'ATA'

or even...

 select  * 
 from    item 
 where   long_word_string regexp '1GB RAM|ATA'

but those are very inefficient/costly methods... and it is better to just normalize things so you're not storing extra data and killing performance trying to get it out

does that make sense? does it answer your question?

edit: my answer lost out to just two tables... i'm concerned for OP's database now.

Thanks for all the suggestions. IT was very helpfull. I think I will try go for the seperated table for key Words, but im not sure how to code this part, so will have start learn that too :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top