maxwell@;10988405 wrote:
My main table has lots of columns, containing the information that I want to display, including one called keyword_id.
In this field I have placed keyword_id(s) relevant to that row, each separated with a space, one row could have 2 4 7 or 1 2 4 6 7 8
This breaks one of the Normal Forms (NF). Iirc, it's First NF (1NF), the lowest level of database normalization, you break by storing compound values in one field. Wikipedias article on database normalization is a good read for an intro to this topic.
What you need to do is create a new table with two fields, one being the primary key from your titles table, the other being primary keys from your keyword table. So instead of having
table: titles
id software_id other stuff
1 1 5 6 9
You'd have
table: titles
id other stuff
1
table: title_keywords
title_id keyword_id
1 1
1 5
1 6
1 9
You really should read up on database normalization, but there are a few things I'd like to point out straight away, since there are several issues with your approach that will be hard to handle.
With your present approach, let's say you have
id software_id other stuff
1 2 13 24 35
and write a query such as you asked for help with, i.e.
SELECT ... FROM titles WHERE sofware_id LIKE '%3%' OR LIKE '%5%'
First off, using a % at the beginning of your string literal means string indexing can't be used, and this slows down the query considerably. Secondly, with this approach, you will not get what you want, since the 3 match the threes in both 13 and 35, and the 5 match the five in 35. So you'd need to modify your code to include whitespaces
... LIKE '% 2 %'
which will NOT match the 2 in 24, since there's no whitespace following the 2. However, it's not matching the first 2 either, since there is no whitespace before the first character. Which you could solve by storing a whitespace before all ids and one after all ids, or resort to regexp matching instead.
Compare all of these issues with one simple join and a very easy where clause
SELECT ... FROM ...
INNER JOIN title_keywords tk ON title.id = tk.title_id
WHERE tk.keyword_id = 2
The second issue regards updates. Let's say you want to delete id 24. How do you do it? Retrieve all rows containing 24 in the string, process all of these rows programatically by parsing the string and splitting it up in everything before 24 and everything after 24, concatenating these parts together and then updating the table. I get tired by just writing what you have to do.
Compare that to
-- Remove the keyword from all titles
DELETE FROM title_keywords WHERE keyword_id = 24;
-- Remove the keyword from a title with a specific id
DELETE FROM title_keywords WHERE keyword_id = 24 and title_id = 1;
-- Remove the keyword from a title found by some other means
DELETE FROM title_keywords tk
INNER JOIN titles ON tk.title_id = title.id
WHERE title.something = 'some_value' AND tk.keyword_id = 24