Ben URL'lerin bir tablo var ve ben herhangi bir yinelenen URL'leri istemiyorum. Nasıl bir URL verilen PHP / MySQL kullanarak tablosunda zaten olup olmadığını görmek için kontrol edebilirim?
Eğer çiftleri olmasını istemiyorsanız size aşağıdaki yapabilirsiniz:
Birden fazla kullanıcı DB veri eklemek durumunda, yöntem @ önerdiği Jeremy Ruten, olabilir lead to an error: Eğer yapılan bir çek birisi tabloya benzer veri ekleyebilirsiniz.
Başlangıçtaki soruyu cevaplamak için, bir yinelenen olup olmadığını kontrol etmek için kolay yolu eklemek için çalışıyoruz ne karşı bir SQL sorgusu çalıştırmak için!
Örneğin, tabloda url http://www.example.com/
için kontrol etmek istediğiniz edildi links
, daha sonra sorgu gibi bir şey olmazdı
SELECT * FROM links WHERE url = 'http://www.example.com/';
PHP kodu böyle bir şey olmazdı
$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 ($ conn, "url = 'http://www.example.com/' linkleri SELECT * FROM");
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');
}
Ben tüm veritabanı, vb zaten bir veritabanına bir bağlantı var olacak büyük olasılıkla bağlanma ile, el yazısıyla burada bu yazdım, bu yüzden (([{0 yerine yeni bir bağlantı başlayan bu kullanmak yerine gerekir )]} mysql_query
komuta ve mysql_connect
ve mysql_select_db
ile yapılacak şeyler kaldırmak)
Tabii ki, PDO'de gibi, veritabanına bağlanma veya bir ORM veya benzer kullanarak başka yolları vardır, bu yüzden zaten bu kullanıyorsanız, bu cevap alakalı olmayabilir (ve vermek için biraz kapsamı dışındadır muhtemelen Burada bununla ilgili cevaplar!)
Ancak, MySQL ilk etapta Bunu önlemek için birçok yol sağlar.
Öncelikle, "benzersiz" olarak bir alanı işaretleyebilirsiniz.
Ben sadece tüm site bağlı URL'leri ve onlar tarafından ziyaret edilmiştir son kez saklamak istediğiniz bir tablo var diyelim.
Benim tanımı şöyle görünebilir: -
CREATE TABLE links
(
url VARCHAR(255) NOT NULL,
last_visited TIMESTAMP
)
Bu benim bu olay durdurmak için yukarıdaki benzer bazı PHP kod yazdı sürece bana, tekrar tekrar aynı URL'yi eklemek için izin verecek.
Ancak, değiştirmek benim tanımı vardı
CREATE TABLE links
(
url VARCHAR(255) NOT NULL,
last_visited TIMESTAMP,
PRIMARY KEY (url)
)
Ben iki kez aynı değeri eklemek için çalıştı o zaman bu mysql bir hata atmak olur.
PHP bir örnek olacaktır
$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');
}
Bu koştu varsa, ilk denemede bulmak istiyorum, komut açıklama ile öleceği Could not Insert Row 2
. Ancak, sonraki koşulara, bu Could not Insert Row 1
ölürüm.
MySQL url tablonun Primary Anahtar olduğunu biliyor olmasıdır. A Birincil anahtar o satır için benzersiz bir tanımlayıcı. Çoğu zaman, bu bir numara olmak için bir satır için benzersiz bir tanımlayıcı ayarlamak için yararlıdır. MySQL bu metni arıyor daha numaraları ararken daha çabuk olmasıdır. MySQL içinde, tuşları (ve espescially İlköğretim Keys) iki tablo arasındaki ilişkileri tanımlamak için kullanılır. Biz kullanıcılar için bir tablo vardı Örneğin, biz olarak tanımlamak olabilir
CREATE TABLE users (
username VARCHAR(255) NOT NULL,
password VARCHAR(40) NOT NULL,
PRIMARY KEY (username)
)
Biz kullanıcı yapmış bir yazı hakkında bilgi saklamak istedim Ancak, biz sonrası o kullanıcıya ait olduğunu belirlemek için bu yazı ile adını saklamak gerekiyor.
Zaten MySQL hızlı dizeleri daha numaralarını bakarak olduğunu ifade ettik, bu yüzden biz yoktu zaman dizeleri ararken vakit olurdu anlamına gelir.
Bunu çözmek için, fazladan bir sütun, user_id eklemek ve birincil anahtar (bir yazı tabanlı kullanıcı kaydını ararken bu yüzden, biz daha hızlı bulabilirsiniz) o yapabilir
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`)
)
Otomatik artma - Ben de burada yeni bir şey ekledim fark edeceksiniz. Bu temelde bize bu alanı kendisi bakmak izin verir. Yeni bir satır eklenir her zaman, önceki sayısından 1 ekler ve böylece biz numaralandırma hakkında endişelenmenize gerek yok, mağazalar, ve sadece bu kendini yapalım yapabilirsiniz.
Yani, yukarıdaki tablo ile, bizim gibi bir şey yapabilirsiniz
INSERT INTO users (username, password) VALUES('Mez', 'd3571ce95af4dc281f142add33384abc5e574671');
ve daha sonra
INSERT INTO users (username, password) VALUES('User', '988881adc9fc3655077dc2d4d757d480b5ea0e11');
Biz veritabanından kayıtları seçtiğinizde, biz şu olsun: -
mysql> SELECT * FROM users;
+---------+----------+------------------------------------------+
| user_id | username | password |
+---------+----------+------------------------------------------+
| 1 | Mez | d3571ce95af4dc281f142add33384abc5e574671 |
| 2 | User | 988881adc9fc3655077dc2d4d757d480b5ea0e11 |
+---------+----------+------------------------------------------+
2 rows in set (0.00 sec)
Ancak, burada - bir sorun var - biz hala aynı kullanıcı adı ile başka bir kullanıcı ekleyebilirsiniz! Açıkçası, bu bizim yapmak istediğimiz bir şeydir!
mysql> SELECT * FROM users;
+---------+----------+------------------------------------------+
| user_id | username | password |
+---------+----------+------------------------------------------+
| 1 | Mez | d3571ce95af4dc281f142add33384abc5e574671 |
| 2 | User | 988881adc9fc3655077dc2d4d757d480b5ea0e11 |
| 3 | Mez | d3571ce95af4dc281f142add33384abc5e574671 |
+---------+----------+------------------------------------------+
3 rows in set (0.00 sec)
Bizim masa tanımını değiştirmenizi sağlar!
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)
)
Şimdi deneyin ve iki kez aynı kullanıcı eklediğinizde ne olur görelim.
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'
Huzzah! Şimdi biz çalıştığınızda bir hata almak ve ikinci kez adını takın. Yukarıdaki gibi bir şey kullanarak, PHP bu algılayabilir.
Şimdi, geri bağlantıları masaya geçelim, ama yeni bir tanımlama.
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)
)
ve en veritabanına "http://www.example.com" eklemek izin.
INSERT INTO links (url, last_visited) VALUES ('http://www.example.com/', NOW());
Biz denemek ve tekrar takın eğer ....
ERROR 1062 (23000): Duplicate entry 'http://www.example.com/' for key 'url'
Biz bu son ziyaret edildi saatini güncelleştirmek istiyorsanız Ama ne olur?
Peki, biz gibi pek, PHP ile karmaşık bir şey yapabilirsiniz: -
$ Result = mysql_query ($ conn, "url = 'http://www.example.com/' linkleri SELECT * FROM");
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');
}
}
Ya da, hatta veritabanında satırın id kapmak ve güncelleştirmek için kullanabilirsiniz.
$ Result = mysql_query ($ conn, "url = 'http://www.example.com/' linkleri SELECT * FROM");
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');
}
}
Fakat, MySQL REPLACE INTO
denilen bir özellik dahili Yaptı var
Nasıl çalışıyor görelim.
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)
REPLACE INTO
kullanırken, bu last_visited zaman güncellenir ve bir hata atılmış değil dikkat edin!
MySQL bir satır yerine çalışıyorsanız olduğunu tespit olmasıdır. Eğer benzersiz olmak url kurdum gibi, istediğiniz satırı bilir. MySQL (bu durumda, url) bu benzersiz olmalıdır geçirilen bit kullanarak ve bu satır için diğer değerleri güncelleyerek yerine satır rakamlar. Ayrıca link_id güncellenir - biraz beklenmedik olduğu! (Ben sadece ne gördüm kadar Aslında, ben böyle olacağını bilmiyordum!)
Ama ne yeni bir URL eklemek istedim? Bir eşleşen benzersiz satır bulamazsa Peki, REPLACE INTO
mutlu bir yeni bir satır eklemek olacak!
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)
Ben bu soruya cevap ve MySQL'in nasıl çalıştığı hakkında biraz daha bilgi verir umarım!
Eğer çok iyi bir tavsiye çok diğer yanıtlar varsa .. aynı dize vardır URL'ler hakkında tamamen endişe duyuyorlar. Ya da kanonizasyon konusunda endişelenmenize gerek yok?
Örneğin: http://google.com ve http://go%4fgle.com aynı URL, ancak herhangi bir veri tabanı sadece teknikleri ile çiftleri olarak izin verilecek. Bu bir sorun ise, URL'leri gidermek ve karakter kaçış dizileri için gereken preprocess.
URL'ler size nereden geldiğini bağlı olarak da parametreleri hakkında ve bunların uygulamada önemli olup olmadığını endişelenmenize gerek olacaktır.
First, prepare the database.
UNIQUE (url, resource_locator)
.Second, prepare the URL.
Sondaki karakterleri kırparak düşünün. Örneğin, amazon.com noktadan aynı ürün için bu iki URL'ler. Muhtemelen ikinci versiyonu değil, ilk saklamak istiyorum.
http://www.amazon.com/Systemantics-Systems-Work-Especially-They/dp/070450331X
Decode URL'leri kodlanmış. (php's urldecode() function bakın. Dikkatle eksiklikleri Not o sayfanın açıklamalarda belirtildiği gibi.) Şahsen, ben yerine bir çok istemci kodu daha veritabanında dönüşümler bu tür idare ediyorum. Bu tablolar ve görünümler izinleri iptal ve ekler ve güncellemeleri sadece depolanmış prosedürleri aracılığıyla izin içerecektir; Saklı yordamlar bir kanonik forma URL koymak tüm dize işlemleri işlemek. Bunu denemek Ama performansı üzerinde bir göz tutmak. FİYATLARI () kısıtlamaları (yukarıya bakınız) güvenlik ağı vardır.
Third, yalnızca URL ekleyerek eğer, don't test for its existence first. Bunun yerine, değer zaten varsa alırsınız hata eklemek ve tuzak deneyin. Test ve yerleştirme her yeni URL için iki veritabanı vurur. Takın ve-tuzak sadece bir kez veritabanını vurur. Insert-ve-trap insert-ve-görmezden-hataları gibi aynı şey olmadığını dikkatlice unutmayın. Sadece belirli bir hata benzersiz kısıtlamayı ihlal anlamına gelir; diğer hatalar başka sorunlar var anlamına gelir.
Eğer aynı satırda bazı diğer verilerle birlikte URL ekleyerek eğer Öte yandan, sen yinelenen adresler idare edeceğiz olsun vaktinden karar vermeniz gerekir
DEĞİŞTİR tuzak anahtar hataları çoğaltmak ihtiyacını ortadan kaldırır, ancak yabancı anahtar başvuruları varsa o talihsiz yan etkileri olabilir.
Eğer benzersiz bir kısıtlama eklemek gerekir teklik garanti. Lütfen tablo adı "URL'ler" ve sütun adı "url" olduğunu varsayarak, bu alter tablo komutu ile benzersiz kısıtlamayı ekleyebilirsiniz:
alter table urls add constraint unique_url unique (url);
Zaten zaten tabloda yinelenen adresler var ise alter tablo muhtemelen (kim gerçekten MySQL ile bilir) başarısız olacaktır.
Basit bir SQL çözümleri, eşsiz bir alanı gerektirir; mantık çözüm yok.
Sen hiçbir çoğaltılması olmadığından emin olmak için adresler normalleştirmek gerekmektedir. Böyle strtolower() ve urldecode() veya rawurldecode() olarak PHP Fonksiyonlar.
Varsayımlar: Sizin tablo adı url için sütun adı 'url' ve url ile ilişkili keyfi veri sütun 'veri' olduğunu, 'web' dir.
Logic Solutions
SELECT COUNT(*) AS UrlResults FROM websites WHERE url='http://www.domain.com'
SQL veya PHP ifadeleri bir INSERT deyimi ile devam önce 0 olduğundan emin olmak için eğer bir önceki sorgusu sınamak.
Simple SQL Statements
Scenario 1: Senin db ilk hizmet ilk gelen tablo olduğunu ve gelecekte yinelenen girdileri için hiçbir arzusu var.
ALTER TABLE websites ADD UNIQUE (url)
Bu url değeri zaten o sütundaki varsa veritabanına girilecek edememek herhangi girişleri engellemek olacaktır.
Scenario 2: Her url için güncel bilgileri en çok istediğiniz ve içerik çoğaltmak istemiyorum. Bu senaryo için iki çözüm vardır. (Bu çözümler de Scenario 1 da yürütülen gerekir bu yüzden çözüm benzersiz olması için 'url' gerektirir.)
REPLACE INTO websites (url, data) VALUES ('http://www.domain.com', 'random data')
O kadar bildirimleri ON DELETE ile dikkatli değilse bir satır INSERT varsa ve eğer bu bir DELETE eylemi tetikler.
INSERT INTO websites (url, data) VALUES ('http://www.domain.com', 'random data')
ON DUPLICATE KEY UPDATE data='random data'
Yoksa, bir satır, bir INSERT varsa ve eğer bu bir UPDATE eylemi tetikler.
Bu soruna bir çözüm düşünüyor, önce bir "yinelenen URL" Projeniz için ne demek olduğunu tanımlamak gerekir. Bu veritabanına eklemeden önce nasıl canonicalize URL'ler belirleyecektir.
En az iki tanım vardır:
%C3%84
UTF-8 'A' temsil) sonucuna varamayız http://google.com/?q=A%CC%88 (%CC%88
temsil aynıdır ö BİRLEŞTİRİLMESİ U 0308).www.
' bir URL yetki sadece kaldırılamaz (1)]} HTTP başlık ve bazı web sunucuları bu başlığına dayanarak geri farklı içerik göndermek için sanal konakları kullanmak. Daha genel olarak, alan adları aynı IP adresine çözümlemek bile, başvurulan kaynakların aynı olduğu sonucuna varamayız.www.
' şerit olacak. Sen gereksiz URL'leri parçaları her türlü kaldırmak için, PHP taşıdık PostRank en postrank-uri kodunu kullanabilirsiniz (örneğin, &utm_source=...
).Tanım 1 kararlı bir çözüm (yani yapılabilir ve bir URL kurallı değişiklik olmayacak başka kurallı yoktur) yol açar. Ben bir insan URL kurallı tanımı ne düşündüğü olduğunu düşünüyorum tanımı 2, zaman içinde farklı anlarda farklı sonuçlar verebilir bir meşrulaştırma rutin yol açar.
Hangisini seçerseniz seçin tanım, ben düzeni, giriş, host, port, ve yol bölümleri için ayrı sütunlar kullanmanızı öneririz. Bu akıllıca dizinleri kullanmanızı sağlayacak. Şeması ve konak için sütunlar (tüm karakter alfabe harf duyarsız MySQL olan) bir karakter harmanlama kullanabilirsiniz, ancak giriş ve yolu için sütunlar bir ikili, harf duyarsız harmanlama kullanmak gerekir. Eğer Tanımı 2 kullanıyorsanız bazı kurallı kurallar zaman eklenen veya zaman kaldırılır olabilir gibi Ayrıca, sen, orijinal düzeni, otoriteyi, ve yol bölümlerini korumak gerekir.
EDIT: İşte örnek tablo tanımları şunlardır:
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';
Tablo `urls1` tanımına 1'e göre kanonik URL'leri saklamak içindir. Tablo `urls2` tanımına 2'ye göre kanonik URL'leri saklamak içindir.
Ne yazık ki MySQL uzunluğunu sınırlar gibi başlığın üzerinde bir UNIQUE
kısıtlaması (`şema` / `canonical_scheme`, `canonical_login`, `canonical_host`, `liman`, `canonical_path`) belirtmek mümkün olmayacaktır 767 bayt InnoDB anahtarların.
i MySQL için sözdizimi bilmiyorum, ama yapmanız gereken tüm tabloyu sorgulamak IF deyimi ile INSERT sarın ve verilen url ile kayıt varsa, eğer varsa görürsünüz - yeni bir rekor takmayın.
MSSQL Bunu eğer:
IF NOT EXISTS (SELECT 1 FROM YOURTABLE WHERE URL = 'URL')
INSERT INTO YOURTABLE (...) VALUES (...)
İlk şeyler. Zaten tablo oluşturulmuş değil, ya da bir tablo oluşturduk ama içinde veri yoksa o zaman benzersiz bir constriant, ya da benzersiz bir dizin eklemeniz gerekir. Endeksi veya kısıtlamaları arasında seçme hakkında daha fazla bilgi yazının sonunda izler. Ama ikisi de sütun yalnızca benzersiz değerleri içerdiğini uygulanması, aynı şeyi başarmak.
Bu sütun üzerinde benzersiz bir dizin içeren bir tablo oluşturmak için kullanabilirsiniz.
CREATE TABLE MyURLTable(
ID INTEGER NOT NULL AUTO_INCREMENT
,URL VARCHAR(512)
,PRIMARY KEY(ID)
,UNIQUE INDEX IDX_URL(URL)
);
Sadece bu tabloda benzersiz bir kısıtlama ve hiçbir indeks isterseniz kullanabilirsiniz
CREATE TABLE MyURLTable(
ID INTEGER NOT NULL AUTO_INCREMENT
,URL VARCHAR(512)
,PRIMARY KEY(ID)
,CONSTRAINT UNIQUE UNIQUE_URL(URL)
);
Şimdi, zaten bir tablo var, ve hiçbir veri yoksa, o zaman aşağıdaki kod parçalarından biri ile masaya dizin veya kısıtlama ekleyebilirsiniz.
ALTER TABLE MyURLTable
ADD UNIQUE INDEX IDX_URL(URL);
ALTER TABLE MyURLTable
ADD CONSTRAINT UNIQUE UNIQUE_URL(URL);
Şimdi, zaten bunu bazı verilerle bir tablo olabilir. Bu durumda, zaten bunu bazı yinelenen veri olabilir. Yukarıda gösterilen constriant veya dizin oluşturmayı deneyebilirsiniz, ve zaten yinelenen veri varsa başarısız olur. Harika yinelenen verileri, yoksa bunu yaparsanız, size çiftleri kaldırmak gerekecek. Bir aşağıdaki sorguyu kullanarak çiftleri ile URL yaktı görebilirsiniz.
SELECT URL,COUNT(*),MIN(ID)
FROM MyURLTable
GROUP BY URL
HAVING COUNT(*) > 1;
Çoğaltmaları satırları silmek, ve birini tutmak için, aşağıdakileri yapın:
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;
Şimdi tüm kayıtları silinmiş olduğunu, siz devam edin ve size bir dizin veya kısıtlama oluşturabilirsiniz. Eğer veritabanı içine bir değer eklemek istiyorsanız Şimdi, sizin gibi bir şey kullanmak gerekir.
INSERT IGNORE INTO MyURLTable(URL)
VALUES('http://www.example.com');
Bu ekleme yapmak için çalışır, ve bir kopyasını bulursa, hiçbir şey olmaz. Şimdi, böyle bir şey yapabilirsiniz, diğer sütun var diyelim.
INSERT INTO MyURLTable(URL,Visits)
VALUES('http://www.example.com',1)
ON DUPLICATE KEY UPDATE Visits=Visits+1;
Bu değeri eklemek için çalışacağız bakacağız, ve URL bulursa, o zaman ziyaret sayacı arttırılmasıyla kayıt güncelleme olacaktır. Tabii ki, her zaman bir düz eski ekleme yapmak, ve PHP Kodu sonuçlanan hata işleyebilir. Şimdi, kısıtlamaları veya dizinleri kullanmanız gerekip gerekmediğini ya da değil gibi, bu faktörlerin çok bağlıdır. Endeksleri hızlı aramaları için yapmak, böylece tablo büyüdükçe performans daha iyi olacaktır, ancak dizin depolama fazladan yer alacak. Indeksleri de genellikle ekler yapmak ve dizinini güncellemek için çünkü güncellemeleri, hem de daha uzun sürer. Değer eşsizliği güçlendirmek için, ya bir yol baktı gerekecek beri Ancak, bu durumda, sadece zaten endekse sahip daha hızlı olabilir. Ilgili bir şey performans olarak, hem de cevap seçenekleri deneyin ve sizin durumunuza en uygun hangi görmek için sonuçları profili olduğunu.
Bu sorguyu yapabilirsiniz:
SELECT url FROM urls WHERE url = 'http://asdf.com' LIMIT 1
Varsa mysql_num_rows() == 1 görmek için eğer kontrol edin.
Cevabı bir girişim yinelenen bir alana sahip bir kayıt girmek için yapıldığında bilmek istiyorum bağlıdır. Eğer olarak "INSERT ... YİNELENEN KEY" sözdizimi kullanın sonra umurumda değil bu girişimi sessizce bir kopyasını oluşturmadan başarılı yapacaktır.
Öte yandan böyle bir olay olduğunda bilmek ve bunu engellemek istiyorsanız, o zaman teşebbüs ekleme / güncelleme anlamlı bir hata ile başarısız olmasına neden olur benzersiz bir anahtar kısıtlaması kullanmalısınız.
Siz bulun (ve çıkarmak) bir kullanarak yapabilirsiniz self-join. Sizin tablo bazı URL ve ayrıca bazı PK (Biz PK is not URL aksi takdirde çoğaltmaları için izin olmaz çünkü biliyorum)
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
Bu URL'leri çoğaltılamaz tüm satırları dönecektir.
Sadece duplicates seçin ve Eh orijinali neyin karar vermek gerekir .... orijinal dışlamak istediğini, ama, demek. Bu cevabın amacıyla en düşük PK "orijinal" olduğunu varsayalım
Yapmanız gereken tüm Yukarıdaki sorgu için aşağıdaki fıkra eklemektir:
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"
Şimdi tüm orijinal olmayan çoğaltılamaz satır bir dizi var. Kolayca bir DELETE
yürütebilir ya da bu sonuç kümesinden istersen.
Bu yaklaşım mySQL her zaman iyi IN
ele vermez ama bu, masada her zaman bir kontrol "temizlemek" sıralamasını OP anlamak kısmen çünkü verimsiz olabileceğini unutmayın.
Eğer zaten bir değeri olsun veya olmasın INSERT
seferde kontrol etmek istiyorsanız bu gibi bir şey çalıştırabilirsiniz
SELECT
1
WHERE
EXISTS (SELECT * FROM yourTable WHERE [URL] = 'testValue')
Eğer bir sonuç alırsanız, o zaman değeri zaten en az bir kez DB var sonucuna varabiliriz.
Bu yöntem, php kullanarak mysql
<?php
mysql_connect('localhost','root','');
mysql_select_db('db_name');
$url='http://www.stackoverflow.com';
$query=mysql_query("select * from urls where url='".$url."' ") or die(mysql_error());
$duplicate=mysql_num_rows($query);
if($duplicate==0)
{
echo'The url '.$url.' is not present in table. You can add it to table ';
$query1=mysql_query("insert into urls(url) values('".$url."')") or die(mysql_error());
}
else
{
echo'The url '.$url.' is already present in the urls table';
}
?>
Başvuru için: find duplicate entry using php