How to check uniqueness of many-to-many collection?

爱⌒轻易说出口 提交于 2020-01-07 05:39:26

问题


Here's the desired flow of my PHP app (yes, it's vague, but it's easier that way):

  1. User submits a set of, let's say, about 5 objects by integer IDs. (It'll really be more like 15, but let's say 5 for ease.)
  2. App checks if this collection has been submitted before, and saves it in a MySQL database if not
  3. App saves these objects in the database, if they haven't been saved before

(Objects and collections are many-to-many, so there is an objects table, a collections table, and a table relating the two.)

A couple sample flows:


  1. User submits 111, 112, 113, 114
  2. This set is new! The collection is saved.
  3. We've seen objects 111 and 112, but fetch and save the data for 113 and 114, since we haven't.

  1. Another user submits 111, 112, 113, 114
  2. We've seen this collection before. Don't bother saving.
  3. Since we've seen the collection, we've obviously seen the objects. Don't bother saving.

Steps 1 and 3 are simple. Step 2 is where I'm not sure how to proceed. It seems unnecessarily database-heavy to be querying the relationship for sets containing those exact IDs, so I'm about to post a few obvious solutions such as a simple ID list and hashing, but I'd also like to know if there are more ideal solutions out there.

Thanks!


回答1:


One obvious solution is to save a list of children IDs in the collection's database row, e.g 1111,1112,1113,1114,1115. It's quick, easy, and guarantees uniqueness, but I imagine it would be unnecessarily CPU-heavy to compare lists like this, especially if they get long, not to mention that it's a fair amount of duplication when it comes to storage space.




回答2:


Another obvious answer is to take the same concatenated string and take the MD5 hash - quick and easy, but runs the (granted, small) risk of collision. Is hashing worth using by nature of shorter strings, even though I could easily have a 100% guarantee of never having collisions by not hashing?




回答3:


In my application, I will do this step:

  1. After user submit, and before entering to database, I will fetch the data in the database into an array. In your example above, I will have $collection = array('111', '112', '113', '114');
  2. I will check the new user input in two step. First step is to see if it already in the database or not. If it not, then insert. Otherwise ignore:

    foreach ( $inputs as $input )
    {
      if ( ! in_array($input, $collection) )
      {
        //do insert here
      }
    }

Then in second loop, I do it in reverse, to delete the data that not selected by user.

foreach ( $collection as $data )
{
  if ( ! in_array($data, $inputs) )
  {
    //do delete here
  }
}

In your case, you might or might not need the second loop. I needed this since I make the input as checkboxes, that the user can choose to activate / deactivate, thus I translate it as insert and delete.



来源:https://stackoverflow.com/questions/2095633/how-to-check-uniqueness-of-many-to-many-collection

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!