开发者

Problem with an querying an array. (MySQL/PHP)

开发者 https://www.devze.com 2023-02-20 09:08 出处:网络
I have an array of strings inputted by the user from an dynamic form. I want to store each value of the array into a table along with an itemid (which is the same for all)

I have an array of strings inputted by the user from an dynamic form. I want to store each value of the array into a table along with an itemid (which is the same for all)

My query is currently inserting the whole array into one row's text_value with implode.

Is there a way instead of looping through the array and running a query for each value in the array, for me to query each array value with the itemId.

I was thinking perhaps adding another dimension to the array with the itemId? is this possible?

current query:

$query = "INSERT INTO answers_tb (item_id, text_value)VALUES('$itemid','".implode(',', $answers) . "')";

here is print_r of array:

Array ( [0] => option 1 [1] => option 2 [2] => option 3 [3] => opti开发者_开发技巧on 4 )

here is the table structure I am inserting to (item_id is a foreign key):

**Field**  | **Type**   **Attributes**      
answer_id  | int(11)    PRIMARY KEY 
item_id    | int(11)    FOREIGN KEY                 
text_value | varchar(50) 

the referenced table:

**Field**       | **Type**        | **Attributes**  
item_id      | int(11)    |       PRIMARY KEY               
item_type    | tinyint(1)     |     
user_id      | int(11)    |     
unit_id      | int(11)    |     
question_text    | varchar(100)             
question_text_2  | varchar(100)             
item_desc    | varchar(25)          
item_name    | varchar(25)

thanks


If you structure your table as item_id, astring rather than item_id, alongconcatenatedstring, you could do the insert like this:

$id=2;
$valueclause=function($string) use ($id) { return "('$id','$string')";};
array_walk($valueclause, $arr);

$values=implode(',',$arr);
$query= "INSERT INTO  answers_tb (item_id, text_value) VALUES $values";

ETA: It appears that it might be useful to have a primary key that combines an auto_increment and another column. So given your table struture of:

         **Field**  | **Type**
         answer_id  | int(11)
         item_id    | int(11)
         text_value | varchar(50) 

you might consider indexing like this:

CREATE TABLE answers_tb(
    item_id INT NOT NULL,
    answer_id INT NOT NULL AUTO_INCREMENT,
    text_value CHAR(50) NOT NULL,
    PRIMARY KEY (item_id, answer_id)//note the 2 columns in the key
);

Then when you insert like this:

INSERT INTO  answers_tb (item_id, text_value) 
VALUES (1,'thing'), (1,'foo'), 
       (17,'blah'), 
       (6,'beebel'), (6,'bar');

your resulting data will look like this:

item_id, answer_id, textvalue
1,       1,         thing
1,       2,         foo
17,      1,         blah
6,       1,         beebel
6,       2,         bar


It sounds like you would be better served with a different table design.

Instead of answers_tb (item_id, text_value), use answers_tb (item_id, offset, value).

(The primary key would be (item_id, offset).)

Then you would find it much easier to query the table.

EDIT: You posted the following table structure:

**Field**  | **Type**   **Attributes**
answer_id  | int(11)    PRIMARY KEY
item_id    | int(11)    FOREIGN KEY
text_value | varchar(50)

If I understand the table design right, your design works like this:

  • Each row of the referenced table (let's call it questions) represents a single question asked by a user of your application. It has a question ID, and the ID of the user who posted it.
  • Each row of the table answers_tb represents the set of all answers to the question in the row of table questions referenced by item_id. Answers are distinguished by the order in which they appear in the column entry.

What I'm saying is that this design for answers_tb doesn't work very well, for the reason you've identified: it's difficult to query against the answers stored in the "array" column. That is why this design is problematic. A better design would be as follows:

**Field**     | **Type**
item_id       | int(11)
answer_number | int
text_value    | varchar(50)

wherein item_id is still a foreign key, but the primary key is (item_id, answer_number). In this design, each row of the table, rather than containing the set of all answers to the corresponding question, would contain just one answer to that question. The rows are distinguished from one another by the different values in answer_number, but you know which question each row corresponds to by the value in item_id. This design is much easier to query against.

It is a general rule that you ought not to try to store an array of data in a column, because it makes it problematic to search against. In some cases it makes sense to break that rule, but you have to be able to recognise when you are in such a case. In this case, you want to search by the stored values, so you should not do it.

0

精彩评论

暂无评论...
验证码 换一张
取 消