복붙노트

[SQL] 값이 이미 피할 중복에 존재하는지 확인하는 방법?

SQL

값이 이미 피할 중복에 존재하는지 확인하는 방법?

나는 URL을 테이블을 가지고 내가 중복 URL을 원하지 않는다. 어떻게 특정 URL은 PHP / MySQL을 사용 테이블에 이미 있는지 확인합니까?

해결법

  1. ==============================

    1.당신은 당신이 다음을 수행 할 수 있습니다 중복을 갖고 싶어하지 않는 경우 :

    당신은 당신이 다음을 수행 할 수 있습니다 중복을 갖고 싶어하지 않는 경우 :

    여러 사용자가 DB, @Jeremy Ruten에 의해 제안 방법에 데이터를 삽입 할 수있는 경우, 오류가 발생할 수 있습니다 : 당신이 체크 누군가가 테이블에 유사한 데이터를 삽입 할 수 있습니다 수행 한 후에.

  2. ==============================

    2.초기 질문에 대답하기 가장 쉬운 방법 중복이 있는지 확인하면 추가하려고하는지에 대해 SQL 쿼리를 실행하는 것입니다!

    초기 질문에 대답하기 가장 쉬운 방법 중복이 있는지 확인하면 추가하려고하는지에 대해 SQL 쿼리를 실행하는 것입니다!

    예를 들어, 다음 쿼리 같이 보일 것입니다 테이블 링크의 URL을 http://www.example.com/를 확인 할 수 있었

    SELECT * FROM links WHERE url = 'http://www.example.com/';
    

    귀하의 PHP 코드는 같을 것이다

    $conn = mysql_connect('localhost', 'username', 'password');
    if (!$conn)
    {
        die('Could not connect to database');
    }
    if(!mysql_select_db('mydb', $conn))
    {
        die('Could not select database mydb');
    }
    
    $result = mysql_query("SELECT * FROM links WHERE url = 'http://www.example.com/'", $conn);
    
    if (!$result)
    {
        die('There was a problem executing the query');
    }
    
    $number_of_rows = mysql_num_rows($result);
    
    if ($number_of_rows > 0)
    {
        die('This URL already exists in the database');
    }
    

    나는 모든 당신이 사용해야 있도록, 당신은 이미 데이터베이스에 연결이 될 가능성이 높습니다 등, 데이터베이스에 연결하는 대신 새 연결을 시작하는 긴 형식 여기를 서면으로 작성했습니다합니다 (에 $ CONN 교체 는 mysql_query 명령과 물건을 제거)이 된 mysql_connect 및 반환 mysql_select_db 함께 할 수있는

    물론, PDO처럼 데이터베이스에 연결하거나, ORM, 또는 유사한을 사용하는 다른 방법은 이미 그를 사용하는 경우 그래서,이 대답은 관련없는 (그리고 아마도 제공하는 범위를 넘어 조금이다,있다 여기에 관련된과 답변을!)

    그러나 MySQL은 처음에 이런 일이 발생을 방지하기 위해 여러 가지 방법을 제공합니다.

    첫째, 당신은 "독특한"등의 필드를 표시 할 수 있습니다.

    난 그냥 내 사이트에 링크 된 모든 URL을 저장할 테이블, 그들이 방문한 마지막 시간을 말할 수 있습니다.

    나의 정의는 다음과 같이 보일 수 있습니다 -

    CREATE TABLE links
    (
        url VARCHAR(255) NOT NULL,
        last_visited TIMESTAMP
    )
    

    이것은 내가 이런 일을 막을 수있는 위의와 비슷한 PHP 코드를 작성하지 않는 날, 또 다시 같은 URL을 추가 할 수있다.

    그러나 변경 내 정의했다

    CREATE TABLE links
    (
      url VARCHAR(255)  NOT NULL,
      last_visited TIMESTAMP,
      PRIMARY KEY (url)
    )
    

    그런 다음이 내가 두 번 같은 값을 삽입하려고 할 때 MySQL은 오류가 발생 할 것입니다.

    PHP의 예는 것

    $result = mysql_query("INSERT INTO links (url, last_visited) VALUES ('http://www.example.com/', NOW()", $conn);
    
    if (!$result)
    {
        die('Could not Insert Row 1');
    }
    
    $result2 = mysql_query("INSERT INTO links (url, last_visited) VALUES ('http://www.example.com/', NOW()", $conn);
    
    if (!$result2)
    {
        die('Could not Insert Row 2');
    }
    

    당신이 실행하는 경우, 당신은 첫 번째 시도에서, 스크립트가 삽입 행 2. 그러나, 후속 실행에, 그것은 행 삽입 한 수 없습니다 죽을 거라고 할 수 없습니다 코멘트와 함께 죽을 것을 알 것입니다.

    MySQL은 URL이 테이블의 기본 키는 것을 알고 있기 때문이다. 기본 키는 그 행에 대한 고유 식별자이다. 대부분의 시간, 그것은 숫자로 행에 대한 고유 식별자를 설정하는 데 유용합니다. MySQL은 더 빨리 텍스트를 찾는 것보다 번호를 찾고에 있기 때문입니다. MySQL은 내 키 (및 espescially 기본 키)는 두 테이블 간의 관계를 정의하는 데 사용됩니다. 우리는 사용자를위한 테이블이 있다면 예를 들어, 우리는 그것을로 정의 할 수

    CREATE TABLE users (
      username VARCHAR(255)  NOT NULL,
      password VARCHAR(40) NOT NULL,
      PRIMARY KEY (username)
    )
    

    우리는 사용자가 제작 한 게시물에 대한 정보를 저장하고 싶었 그러나, 우리는 포스트 해당 사용자에 속한 것을 확인하는 해당 게시물에 사용자 이름을 저장해야 할 것이다.

    나는 이미 우리는 우리가 가지고 있지 않은 경우 문자열을 찾는 시간을 보낼 것 의미 있도록 MySQL은 빠른 문자열보다 숫자를 찾고에 있음을 언급했다.

    이 문제를 해결하기 위해, 우리는 여분의 열, USER_ID를 추가하고, 기본 키 (게시물에 기초하여 사용자 레코드를 찾을 때 그래서, 우리는 더 빨리 찾을 수) 있음을 만들 수 있습니다

    CREATE TABLE users (
      user_id INT(10)  NOT NULL AUTO_INCREMENT,
      username VARCHAR(255)  NOT NULL,
      password VARCHAR(40)  NOT NULL,
      PRIMARY KEY (`user_id`)
    )
    

    AUTO_INCREMENT를 - 내가 새로운 여기에 뭔가를 추가 한 것을 알 수 있습니다. 이것은 기본적으로 우리가 자체 후 해당 필드의 모양을 수 있도록 할 수 있습니다. 새로운 행이 삽입 될 때마다 이전 번호에 1을 추가하고, 우리가 번호에 대한 걱정을하지 않아도, 상점, 그리고 그냥이 자체 작업을 수행하도록 할 수 있습니다.

    그래서, 위의 표에, 우리는 뭔가를 할 수 있습니다

    INSERT INTO users (username, password) VALUES('Mez', 'd3571ce95af4dc281f142add33384abc5e574671');
    

    그리고

    INSERT INTO users (username, password) VALUES('User', '988881adc9fc3655077dc2d4d757d480b5ea0e11');
    

    우리가 데이터베이스에서 레코드를 선택하면, 우리는 다음을 얻을 : -

    mysql> SELECT * FROM users;
    +---------+----------+------------------------------------------+
    | user_id | username | password                                 |
    +---------+----------+------------------------------------------+
    |       1 | Mez      | d3571ce95af4dc281f142add33384abc5e574671 |
    |       2 | User     | 988881adc9fc3655077dc2d4d757d480b5ea0e11 |
    +---------+----------+------------------------------------------+
    2 rows in set (0.00 sec)
    

    그러나 여기에 - 우리는 문제가있다 - 우리는 여전히 같은 이름으로 다른 사용자를 추가 할 수 있습니다! 분명히, 이것은 우리가하고 싶지 않은 일입니다!

    mysql> SELECT * FROM users;
    +---------+----------+------------------------------------------+
    | user_id | username | password                                 |
    +---------+----------+------------------------------------------+
    |       1 | Mez      | d3571ce95af4dc281f142add33384abc5e574671 |
    |       2 | User     | 988881adc9fc3655077dc2d4d757d480b5ea0e11 |
    |       3 | Mez      | d3571ce95af4dc281f142add33384abc5e574671 |
    +---------+----------+------------------------------------------+
    3 rows in set (0.00 sec)
    

    우리 테이블 정의를 변경할 수 있습니다!

    CREATE TABLE users (
      user_id INT(10)  NOT NULL AUTO_INCREMENT,
      username VARCHAR(255)  NOT NULL,
      password VARCHAR(40)  NOT NULL,
      PRIMARY KEY (user_id),
      UNIQUE KEY (username)
    )
    

    우리가 지금 시도하고 두 번 같은 사용자를 삽입 할 때 어떻게 볼 수 있습니다.

    mysql> INSERT INTO users (username, password) VALUES('Mez', 'd3571ce95af4dc281f142add33384abc5e574671');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> INSERT INTO users (username, password) VALUES('Mez', 'd3571ce95af4dc281f142add33384abc5e574671');
    ERROR 1062 (23000): Duplicate entry 'Mez' for key 'username'
    

    만세 삼창! 우리는 지금 우리가하려고 할 때 오류가 발생하고, 두 번째로 이름을 삽입합니다. 위의 같은 것을 사용하여, 우리는 PHP에서 이것을 감지 할 수 있습니다.

    지금, 우리의 링크 테이블로 돌아가지만, 새로운 정의를 할 수 있습니다.

    CREATE TABLE links
    (
        link_id INT(10)  NOT NULL AUTO_INCREMENT,
        url VARCHAR(255)  NOT NULL,
        last_visited TIMESTAMP,
        PRIMARY KEY (link_id),
        UNIQUE KEY (url)
    )
    

    데이터베이스로의 삽입 "http://www.example.com"을 할 수 있습니다.

    INSERT INTO links (url, last_visited) VALUES ('http://www.example.com/', NOW());
    

    우리가 시도하고 다시 삽입하면 ....

    ERROR 1062 (23000): Duplicate entry 'http://www.example.com/' for key 'url'
    

    우리가 마지막으로 방문했던 시간을 업데이트 할 경우 어떻게 될까요?

    음, 우리는 그렇게 같은 PHP 복잡한 무언가를 할 수 : -

    $result = mysql_query("SELECT * FROM links WHERE url = 'http://www.example.com/'", $conn);
    
    if (!$result)
    {
        die('There was a problem executing the query');
    }
    
    $number_of_rows = mysql_num_rows($result);
    
    if ($number_of_rows > 0)
    {
        $result = mysql_query("UPDATE links SET last_visited = NOW() WHERE url = 'http://www.example.com/'", $conn);
    
        if (!$result)
        {
            die('There was a problem updating the links table');
        }
    }
    

    또는, 심지어 데이터베이스에서 행의 ID를 잡고 그것을를 업데이트하기 위해 사용한다.

    $ 결과 =는 mysql_query이 ( "링크 SELECT * FROM WHERE URL = 'http://www.example.com/'", $ CONN);

    if (!$result)
    {
        die('There was a problem executing the query');
    }
    
    $number_of_rows = mysql_num_rows($result);
    
    if ($number_of_rows > 0)
    {
        $row = mysql_fetch_assoc($result);
    
        $result = mysql_query('UPDATE links SET last_visited = NOW() WHERE link_id = ' . intval($row['link_id'], $conn);
    
        if (!$result)
        {
            die('There was a problem updating the links table');
        }
    }
    

    하지만, MySQL은 기능 내장 좋은이 INTO 교체라는있다

    이제 어떻게 작동하는지 살펴 보자.

    mysql> SELECT * FROM links;
    +---------+-------------------------+---------------------+
    | link_id | url                     | last_visited        |
    +---------+-------------------------+---------------------+
    |       1 | http://www.example.com/ | 2011-08-19 23:48:03 |
    +---------+-------------------------+---------------------+
    1 row in set (0.00 sec)
    
    mysql> INSERT INTO links (url, last_visited) VALUES ('http://www.example.com/', NOW());
    ERROR 1062 (23000): Duplicate entry 'http://www.example.com/' for key 'url'
    mysql> REPLACE INTO links (url, last_visited) VALUES ('http://www.example.com/', NOW());
    Query OK, 2 rows affected (0.00 sec)
    
    mysql> SELECT * FROM links;
    +---------+-------------------------+---------------------+
    | link_id | url                     | last_visited        |
    +---------+-------------------------+---------------------+
    |       2 | http://www.example.com/ | 2011-08-19 23:55:55 |
    +---------+-------------------------+---------------------+
    1 row in set (0.00 sec)
    

    INTO 교체 사용시주의 사항, 그것은 last_visited 시간을 업데이트하고 있다고 오류가 발생하지!

    MySQL은 당신이 행을 대체하려고 시도하고 있음을 감지하기 때문이다. 당신은 고유의 URL을 설정 한 것처럼, 당신이 원하는 행을 알고있다. 행 아웃 MySQL의 수치는 해당 행에 다른 값 및 업데이트 (이 경우, URL의) 고유해야 당신이 전달하는 비트를 사용하여 교체 할 수 있습니다. 조금 의외입니다 - 또한 LINK_ID 업데이트입니다! (사실, 난 그냥 일어날 볼 때까지 이럴 줄 몰랐어요!)

    하지만 새 URL을 추가 할 것을 원한다면? 그것은 일치하는 고유 한 행을 찾을 수없는 경우 글쎄, INTO 행복하게 새 행을 삽입합니다 교체!

    mysql> REPLACE INTO links (url, last_visited) VALUES ('http://www.stackoverflow.com/', NOW());
    Query OK, 1 row affected (0.00 sec)
    
    mysql> SELECT * FROM links;
    +---------+-------------------------------+---------------------+
    | link_id | url                           | last_visited        |
    +---------+-------------------------------+---------------------+
    |       2 | http://www.example.com/       | 2011-08-20 00:00:07 |
    |       3 | http://www.stackoverflow.com/ | 2011-08-20 00:01:22 |
    +---------+-------------------------------+---------------------+
    2 rows in set (0.00 sec)
    

    나는이 질문에 응답하고 당신에게 MySQL이 어떻게 작동하는지에 대해 좀 더 정보를 제공 바랍니다!

  3. ==============================

    3.그래서 다른 답변에서 좋은 조언을 많이가있는 경우 당신은 ... 순수하게 동일한 문자열입니다 URL에 대해 우려하고있다. 또는 당신은 또한 시성에 대해 걱정할 필요가 있습니까?

    그래서 다른 답변에서 좋은 조언을 많이가있는 경우 당신은 ... 순수하게 동일한 문자열입니다 URL에 대해 우려하고있다. 또는 당신은 또한 시성에 대해 걱정할 필요가 있습니까?

    http://google.com 및 예 : http : //go%4fgle.com 동일한 URL하지만, 데이터베이스의 유일한 기술에 의해 중복으로 허용 될 것이다. 이 문제는 경우에 당신은 해결 및 문자 이스케이프 시퀀스에 URL을 사전 처리해야한다.

    URL이 당신이 어디에서 오는 따라 또한 매개 변수에 대한 걱정과 그들이 응용 프로그램의 중요 여부를해야합니다.

  4. ==============================

    4.첫째, 데이터베이스를 준비합니다.

    첫째, 데이터베이스를 준비합니다.

    둘째, URL을 준비합니다.

    당신은 단지 URL을 삽입하는 경우 셋째, 처음 그 존재에 대한 테스트를하지 않습니다. 대신, 값이 이미 존재하는 경우 당신이 얻을거야 오류를 삽입하고 함정하려고합니다. 테스트마다 새로운 URL에 대해 두 번 안타를 데이터베이스에 삽입. 삽입 앤 트랩은 한 번만 데이터베이스를 맞았습니다. 삽입 앤 트랩이 삽입 - 및 - 무시 - 오류와 같은 일이 아님을주의 깊게합니다. 하나의 특정 오류 수단 당신은 고유 제한 조건을 위반; 다른 오류는 다른 문제가있는 것을 의미한다.

    같은 행에있는 다른 데이터와 함께 URL을 삽입하는 경우 반면에, 당신은 당신이에 의해 중복 된 URL을 처리 할 수 ​​있습니다 여부를 미리 결정해야

    을 제거해에게 트랩 중복 키 오류에 대한 필요성을 교체하지만, 외래 키 참조가있는 경우는 불행한 부작용이있을 수 있습니다.

  5. ==============================

    5.당신이 고유 제한 조건을 추가 할 필요가 고유성을 보장합니다. "URL이"테이블 이름입니다 가정 및 열 이름이 "URL", 당신은이 테이블 변경 명령을 사용하여 고유 제한 조건을 추가 할 수 있습니다 :

    당신이 고유 제한 조건을 추가 할 필요가 고유성을 보장합니다. "URL이"테이블 이름입니다 가정 및 열 이름이 "URL", 당신은이 테이블 변경 명령을 사용하여 고유 제한 조건을 추가 할 수 있습니다 :

    alter table urls add constraint unique_url unique (url);
    

    이미 이미 테이블에 중복 된 URL을 가지고있는 경우 테이블 변경은 아마도 (누가 정말 MySQL과 아는) 실패합니다.

  6. ==============================

    6.간단한의 SQL 솔루션은 고유 필드를 필요로; 로직 솔루션은하지 않습니다.

    간단한의 SQL 솔루션은 고유 필드를 필요로; 로직 솔루션은하지 않습니다.

    당신은 더 중복이없는 확인하기 위해 URL을 정상화해야한다. 이러한하여 strtolower ()와 URLDECODE () 또는 rawurldecode로 PHP의 함수 ().

    가정 : 귀하의 테이블 이름이 '웹 사이트'인,의 열 이름 귀하의 URL입니다 'URL'및 URL이 열 '데이터'에 함께 임의의 데이터가 관련 될 수 있습니다.

    로직 솔루션

    SELECT COUNT(*) AS UrlResults FROM websites WHERE url='http://www.domain.com'
    

    SQL 또는 PHP에서 문이 INSERT 문을 계속하기 전에이 0인지 확인하는 경우와 이전 쿼리를 테스트합니다.

    간단한 SQL 문

    시나리오 1 : 귀하의 DB는 먼저 첫 번째 와서 테이블을 제공하고 미래에 중복 항목을 가지고있는 욕망이없는 것입니다.

    ALTER TABLE websites ADD UNIQUE (url)
    

    이 URL 값이 이미 해당 열에있는 경우 데이터베이스에 입력 할 수있는에서 모든 항목을 방지 할 수 있습니다.

    시나리오 2 : 당신은 각 URL에 대한 가장 최신 정보를 원하는 컨텐츠를 복제하고 싶지 않아요. 이 시나리오의 두 가지 해결책이 있습니다. (시나리오 1에서 솔루션도 수행해야합니다 있도록이 솔루션은 고유해야 'URL을'이 필요합니다.)

    REPLACE INTO websites (url, data) VALUES ('http://www.domain.com', 'random data')
    

    행이 모든 경우에 INSERT 다음에 존재하는 경우이 그렇게 DELETE 선언 ON 조심하는 DELETE 조치를 트리거합니다.

    INSERT INTO websites (url, data) VALUES ('http://www.domain.com', 'random data')
    ON DUPLICATE KEY UPDATE data='random data'
    

    그렇지 않은 경우는 UPDATE 동작 행이 존재하는 경우와 INSERT를 트리거합니다.

  7. ==============================

    7.이 문제에 대한 해결책을 고려할 때, 먼저 프로젝트를 위해 무엇을 "중복 URL"수단을 정의해야합니다. 이 데이터베이스에 추가하기 전에 URL을 정규화하는 방법을 결정합니다.

    이 문제에 대한 해결책을 고려할 때, 먼저 프로젝트를 위해 무엇을 "중복 URL"수단을 정의해야합니다. 이 데이터베이스에 추가하기 전에 URL을 정규화하는 방법을 결정합니다.

    적어도 두 가지 정의가 있습니다 :

    정의 안정한 용액 1 개 리드 (즉, 수행 될 수있는 상기 정규화 변경되지하는 URL의 정규화가 없다). 내가 생각하는 정의 (2)는, 인간이 URL 정규화, 시간에 다른 순간에 서로 다른 결과를 얻을 수있는 정형화 루틴으로 리드의 정의를 고려하는 것이다.

    당신이 선택하든 정의, 당신이 계획, 로그인, 호스트, 포트 및 경로 부분에 대해 별도의 열을 사용하는 것이 좋습니다. 이것은 당신이 지능적으로 인덱스를 사용 할 수 있습니다. 방식과 호스트에 대한 열은 문자 정렬 (모든 문자 데이터 정렬은 대소 문자를 구분 MySQL의에) 사용할 수 있지만 로그인 및 경로의 필요성에 대한 열 이진, 대소 문자를 구분 데이터 정렬을 사용 할 수 있습니다. 당신이 정의 2를 사용하는 경우 또한, 당신은 어떤 정규화 규칙을 추가하거나 수시로 제거 될 수 있습니다로, 원래의 계획, 권한 및 경로 부분을 보존해야합니다.

    편집 : 여기에 예를 들어, 테이블 정의는 다음과 같습니다

    CREATE TABLE `urls1` (
        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
        `scheme` VARCHAR(20) NOT NULL,
        `canonical_login` VARCHAR(100) DEFAULT NULL COLLATE 'utf8mb4_bin',
        `canonical_host` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_unicode_ci', /* the "ci" stands for case-insensitive. Also, we want 'utf8mb4_unicode_ci'
    rather than 'utf8mb4_general_ci' because 'utf8mb4_general_ci' treats accented characters as equivalent. */
        `port` INT UNSIGNED,
        `canonical_path` VARCHAR(4096) NOT NULL COLLATE 'utf8mb4_bin',
    
        PRIMARY KEY (`id`),
        INDEX (`canonical_host`(10), `scheme`)
    ) ENGINE = 'InnoDB';
    
    
    CREATE TABLE `urls2` (
        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
        `canonical_scheme` VARCHAR(20) NOT NULL,
        `canonical_login` VARCHAR(100) DEFAULT NULL COLLATE 'utf8mb4_bin',
        `canonical_host` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `port` INT UNSIGNED,
        `canonical_path` VARCHAR(4096) NOT NULL COLLATE 'utf8mb4_bin',
    
        `orig_scheme` VARCHAR(20) NOT NULL, 
        `orig_login` VARCHAR(100) DEFAULT NULL COLLATE 'utf8mb4_bin',
        `orig_host` VARCHAR(100) NOT NULL COLLATE 'utf8mb4_unicode_ci',
        `orig_path` VARCHAR(4096) NOT NULL COLLATE 'utf8mb4_bin',
    
        PRIMARY KEY (`id`),
        INDEX (`canonical_host`(10), `canonical_scheme`),
        INDEX (`orig_host`(10), `orig_scheme`)
    ) ENGINE = 'InnoDB';
    

    표`urls1` 정의는 표 1 'urls2`은 정의 제 2 항에있어서 표준 URL을 저장하기위한 것이다에 따른 표준 URL을 저장하기위한 것이다.

    MySQL은 767 바이트로 이노 키의 길이를 제한 불행하게도 당신은 튜플에 (`scheme` /`canonical_scheme`,`canonical_login`,`canonical_host`,`port`,`canonical_path`을)를 UNIQUE 제약 조건을 지정 할 수 없습니다 .

  8. ==============================

    8.내가 MySQL을위한 구문을 모르지만, 당신이해야 할 모든 테이블을 조회하고 주어진 URL로 기록이 존재하는 경우가 존재하는 경우, 볼 IF 문을 사용하여 INSERT를 포장입니다 - 새로운 레코드를 삽입하지 않습니다.

    내가 MySQL을위한 구문을 모르지만, 당신이해야 할 모든 테이블을 조회하고 주어진 URL로 기록이 존재하는 경우가 존재하는 경우, 볼 IF 문을 사용하여 INSERT를 포장입니다 - 새로운 레코드를 삽입하지 않습니다.

    MSSQL 경우이 작업을 수행 할 수 있습니다 :

    IF NOT EXISTS (SELECT 1 FROM YOURTABLE WHERE URL = 'URL')
    INSERT INTO YOURTABLE (...) VALUES (...)
    
  9. ==============================

    9.당신이 테이블에 URL을 삽입 할 있지만, 그렇지 않은 만 이미 당신이 열 및 INSERT 쿼리 추가에 고유의 contraint을 추가 할 수있는 경우는 오류가 발생하지 않도록 무시합니다.

    당신이 테이블에 URL을 삽입 할 있지만, 그렇지 않은 만 이미 당신이 열 및 INSERT 쿼리 추가에 고유의 contraint을 추가 할 수있는 경우는 오류가 발생하지 않도록 무시합니다.

    예 : INSERT는 INTO URL을 SET URL을 무시 = 'URL - 투 - 삽입'

  10. ==============================

    10.먼저 첫 번째 것들. 이미 테이블을 생성하지 않았거나 테이블을 만들었지 만 다음에 데이터가없는 경우는 고유 constriant, 또는 고유 인덱스를 추가해야합니다. 인덱스 또는 제약 사이의 선택에 대한 자세한 내용은 게시물의 말에 따른다. 그러나 그들은 모두 열은 고유 한 값이 포함되어 있음을 시행, 같은 일을 수행.

    먼저 첫 번째 것들. 이미 테이블을 생성하지 않았거나 테이블을 만들었지 만 다음에 데이터가없는 경우는 고유 constriant, 또는 고유 인덱스를 추가해야합니다. 인덱스 또는 제약 사이의 선택에 대한 자세한 내용은 게시물의 말에 따른다. 그러나 그들은 모두 열은 고유 한 값이 포함되어 있음을 시행, 같은 일을 수행.

    이 칼럼에 고유 인덱스가있는 테이블을 만들려면 사용할 수 있습니다.

    CREATE TABLE MyURLTable(
    ID INTEGER NOT NULL AUTO_INCREMENT
    ,URL VARCHAR(512)
    ,PRIMARY KEY(ID)
    ,UNIQUE INDEX IDX_URL(URL)
    );
    

    방금 고유 제한 조건, 그 테이블에 어떤 인덱스를 원한다면, 당신은 사용할 수 있습니다

    CREATE TABLE MyURLTable(
    ID INTEGER NOT NULL AUTO_INCREMENT
    ,URL VARCHAR(512)
    ,PRIMARY KEY(ID)
    ,CONSTRAINT UNIQUE UNIQUE_URL(URL)
    );
    

    이미 테이블이 있고, 그 안에 데이터가없는 경우 지금, 당신은 다음 코드 조각 중 하나를 테이블에 인덱스 또는 제약 조건을 추가 할 수 있습니다.

    ALTER TABLE MyURLTable
    ADD UNIQUE INDEX IDX_URL(URL);
    
    ALTER TABLE MyURLTable
    ADD CONSTRAINT UNIQUE UNIQUE_URL(URL);
    

    지금, 당신은 이미 일부 데이터 테이블을 가질 수있다. 이 경우, 당신은 이미 일부 중복 데이터가있을 수 있습니다. 당신은 위에 표시된 constriant 또는 인덱스를 만드는 시도 할 수 있습니다, 당신은 이미 중복 데이터가있는 경우 실패합니다. 당신이 큰 중복 데이터가없는 경우 당신이 할 경우, 당신은 중복을 제거해야합니다. 당신은 다음과 같은 쿼리를 사용하여 중복 된 URL의 조명 볼 수 있습니다.

    SELECT URL,COUNT(*),MIN(ID) 
    FROM MyURLTable
    GROUP BY URL
    HAVING COUNT(*) > 1;
    

    중복, 그리고 하나를 유지, 다음을 수행 삭제 행 :

    DELETE RemoveRecords
    FROM MyURLTable As RemoveRecords
    LEFT JOIN 
    (
    SELECT MIN(ID) AS ID
    FROM MyURLTable
    GROUP BY URL
    HAVING COUNT(*) > 1
    UNION
    SELECT ID
    FROM MyURLTable
    GROUP BY URL
    HAVING COUNT(*) = 1
    ) AS KeepRecords
    ON RemoveRecords.ID = KeepRecords.ID
    WHERE KeepRecords.ID IS NULL;
    

    이제 당신은 모든 레코드를 삭제 한 것을, 당신은 가서 당신에게 인덱스 또는 제약 조건을 만들 수 있습니다. 당신이 당신의 데이터베이스에 값을 삽입 할 경우 지금, 당신은 같은 것을 사용한다.

    INSERT IGNORE INTO MyURLTable(URL)
    VALUES('http://www.example.com');
    

    즉, 삽입을하려고 시도하고 중복을 발견하면 아무 일도 일어나지 않습니다. 지금, 당신이 뭔가를 할 수 있습니다, 당신은 다른 열이 있다고 할 수 있습니다.

    INSERT INTO MyURLTable(URL,Visits) 
    VALUES('http://www.example.com',1)
    ON DUPLICATE KEY UPDATE Visits=Visits+1;
    

    즉, 값을 삽입하려고 보일 것이며,이 URL을 발견하면, 그것은 방문 카운터를 증가시켜 기록을 업데이트합니다. 물론, 당신은 항상 평범한 구식 삽입 할 수 있고, 당신의 PHP 코드에서 생성 된 오류를 처리합니다. 지금, 당신은 제약 조건 또는 인덱스를 사용하는지 여부에 관해서는, 그 많은 요인에 따라 달라집니다. 테이블이 커짐에 있지만 인덱스를 저장하는 여분의 공간을 차지하므로 성능이 더 좋을 것 때문에 인덱스는, 빠른 조회에 확인하십시오. 인덱스는 보통 인덱스를 업데이트하기 때문에 삽입 및 업데이트뿐만 아니라 시간이 오래 걸리고. 값이 경우, 고유성을 적용, 어느쪽으로 고개를해야 할 것 때문에, 그것은 단지 어쨌든 인덱스를 가지고 빨리 할 수있다. 관련 아무것도 성능에 관해서는, 대답은 두 가지 옵션을 모두 시도하고 상황에 가장 적합한 볼 수있는 결과를 프로파일입니다.

  11. ==============================

    11.당신은 단지 예, 아니오 대답을 원하는 경우이 구문은 당신에게 최고의 성능을 제공한다.

    당신은 단지 예, 아니오 대답을 원하는 경우이 구문은 당신에게 최고의 성능을 제공한다.

    select if(exists (select url from urls where url = 'http://asdf.com'), 1, 0) from dual
  12. ==============================

    12.방금 확인하려면 확인에는 중복 다음 URL 필드에 고유 인덱스를 추가하지가, 그 방법은 URL, 그냥 정상적으로 삽입 존재하는 경우 명시 적으로 점검 할 필요가없고, 그 다음이 이미있을 경우 삽입합니다 중복 키 오류로 실패합니다.

    방금 확인하려면 확인에는 중복 다음 URL 필드에 고유 인덱스를 추가하지가, 그 방법은 URL, 그냥 정상적으로 삽입 존재하는 경우 명시 적으로 점검 할 필요가없고, 그 다음이 이미있을 경우 삽입합니다 중복 키 오류로 실패합니다.

  13. ==============================

    13.대답은 당신이 시도가 중복 필드와 레코드를 입력하려고 할 때 알고 싶은 여부에 따라 달라집니다. 그런 다음 관심 "INSERT ... ON DUPLICATE KEY"구문을 사용하지 않는 경우이 당신의 시도는 조용히 중복을 만들지 않고 성공할 것 같은.

    대답은 당신이 시도가 중복 필드와 레코드를 입력하려고 할 때 알고 싶은 여부에 따라 달라집니다. 그런 다음 관심 "INSERT ... ON DUPLICATE KEY"구문을 사용하지 않는 경우이 당신의 시도는 조용히 중복을 만들지 않고 성공할 것 같은.

    다른 한편으로는 이러한 이벤트가 발생할 때 알고 싶은 것을 방지 경우에, 당신은 시도 삽입 / 업데이트가 의미있는 오류와 함께 실패합니다 고유 키 제약 조건을 사용해야합니다.

  14. ==============================

    14.

    $url = "http://www.scroogle.com";
    
    $query  = "SELECT `id` FROM `urls` WHERE  `url` = '$url' ";
    $resultdb = mysql_query($query) or die(mysql_error());   
    list($idtemp) = mysql_fetch_array($resultdb) ;
    
    if(empty($idtemp)) // if $idtemp is empty the url doesn't exist and we go ahead and insert it into the db.
    { 
       mysql_query("INSERT INTO urls (`url` ) VALUES('$url') ") or die (mysql_error());
    }else{
       //do something else if the url already exists in the DB
    }
    
  15. ==============================

    15.열을 기본 키를 확인

    열을 기본 키를 확인

  16. ==============================

    16.당신은 자체 조인 사용하여 위치를 확인합니다 (제거) 할 수 있습니다. 귀하의 표는 일부 URL 및 일부 PK (우리는 그렇지 않으면 당신은 중복이 허용되지 않을 것이기 때문에 PK가 URL 아니라는 것을 알고)가

    당신은 자체 조인 사용하여 위치를 확인합니다 (제거) 할 수 있습니다. 귀하의 표는 일부 URL 및 일부 PK (우리는 그렇지 않으면 당신은 중복이 허용되지 않을 것이기 때문에 PK가 URL 아니라는 것을 알고)가

    SELECT
        *
    FROM
        yourTable a
    JOIN
        yourTable b -- Join the same table
            ON b.[URL] = a.[URL] -- where the URL's match
            AND b.[PK] <> b.[PK] -- but the PK's are different
    

    이 중복 된 URL이 모든 행을 반환합니다.

    말은하지만, 당신은 단지 중복을 선택하고 원본을 제외하고 싶다고 .... 그럼 당신은 원본을 구성할지 결정해야합니다. 이 답변의 목적의 가장 낮은 PK는 "원래"이라고 가정하자

    당신이 위의 질의에 다음 절을 추가하면된다 :

    WHERE
        a.[PK] NOT IN (
            SELECT 
                TOP 1 c.[PK] -- Only grabbing the original!
            FROM
                yourTable c
            WHERE
                c.[URL] = a.[URL] -- has the same URL
            ORDER BY
                c.[PK] ASC) -- sort it by whatever your criterion is for "original"
    

    이제 당신은 모든 정품이 아닌 중복 행 집합이 있습니다. 당신은 쉽게 삭제하거나 당신이 무엇을이 결과 세트에서 같은를 실행할 수 있습니다.

    MySQL은 항상 잘 처리하지 않습니다하지만이 정렬 테이블의 "정리", 항상 수표라는 OP에서 이해하기 때문에이 방법은 부분적으로 비효율적 일 수 있습니다.

    당신은 값이 이미 이런 식으로 뭔가를 실행할 수있는 존재 여부를 INSERT시 확인하려면

    SELECT 
        1
    WHERE
        EXISTS (SELECT * FROM yourTable WHERE [URL] = 'testValue')
    

    당신이 결과를 얻을 경우, 당신은 값이 이미 한 번에 적어도 당신의 DB에 존재 결론을 내릴 수있다.

  17. ==============================

    17.이 쿼리를 할 수 :

    이 쿼리를 할 수 :

    SELECT url FROM urls WHERE url = 'http://asdf.com' LIMIT 1
    

    mysql_num_rows도 () == 1이 존재하는지 확인 경우.

  18. from https://stackoverflow.com/questions/61033/how-to-check-if-a-value-already-exists-to-avoid-duplicates by cc-by-sa and MIT license