Chcesz następny identyfikator, czy identyfikator wiersza, który aktualnie wstawiasz? To znaczy, czy identyfikator na końcu kodu płatności powinien być identyfikatorem wiersza, w którym przechowywany jest kod płatności?
Mike,
id wiersza, który aktualnie
wstawiam
6
W takim przypadku połącz wartości podczas ich pobierania, a nie wstawiania. Jest to o wiele łatwiejsze i wykluczasz otrzymanie niewłaściwego identyfikatora lub konieczność uruchomienia aktualizacji - pomyśl, co by się stało, gdyby wiersz, który właśnie wstawiłeś, zostałby zażądany przez innego klienta, zanim aktualizacja miałaby szansę zostać uruchomiona: klient skończy się z nieprawidłowym kodem płatności. W systemie o małym natężeniu ruchu może się to nie zdarzyć, ale nie widzę sensu podejmowania ryzyka.
Dzięki za dwie pierwsze opcje ... Ale trzecia to tylko numer dwa wywołany z PHP .. Nie jestem pewien, co sprawia, że jest to szybsze na dużych bazach danych ...
Gerard ONeill
1
@GerardONeill Usunięto to
ravi404
3
ponieważ pamięć podręczna jest używana do pobierania danych z information_schema.tables, to rozwiązanie nie działa już dla mysql 8.
Możesz uzyskać następną wartość automatycznego zwiększania, wykonując:
SHOW TABLE STATUS FROM tablename LIKE Auto_increment
/*or*/SELECT`auto_increment`FROM INFORMATION_SCHEMA.TABLES
WHERE table_name ='tablename'
Należy pamiętać, że należy nie używać tego zmienić tabelę, należy użyć kolumny auto_increment to zrobić automatycznie zamiast.
Problem polega na tym, że last_insert_id()jest to retrospektywne i dzięki temu można je zagwarantować w ramach bieżącego połączenia.
To dziecko jest perspektywiczne i dlatego nie jest wyjątkowe pod względem połączenia i nie można na nim polegać.
To działałoby tylko w przypadku jednej bazy danych połączeń, ale bazy danych z jednym połączeniem mają dziś zwyczaj stawania się jutro wieloma bazami danych połączeń.
Nie odrzuciłem tego, ale problem z próbą użycia ostatniej wartości autoinkrementacji polega na tym, że może nie być ostatnią, zanim zaczniesz jej używać - bez względu na to, jak szybko zostanie wykonany SELECT i późniejszy WSTAW.
Mike,
@Mike, a co, jeśli zostanie to zrobione w jednym zapytaniu? Coś jak insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'? after insertlast_insert_id()
Użyłbym
1
@binaryLV: Im mniejsza przerwa między SELECT i INSERT, tym mniejsza szansa, że wartość ulegnie zmianie, ale nie wyklucza tego całkowicie. Wyobraź sobie system z tysiącami trafień w bazie danych na minutę - szanse na zmianę wartości dramatycznie wzrosną. Blokowanie tabeli lub wiersza może temu zapobiec, jeśli jest wykonywane jako pojedyncze zapytanie, ale jest to zależne od określonego zachowania silnika bazy danych, które może nie być dobrze udokumentowane. Poszedłbym z kolejnym, UPDATEgdybym też. Ale wolałbym po prostu połączyć te dwie rzeczy w czasie wyświetlania i zaoszczędzić wszystkich kłopotów.
Mike,
3
SHOW TABLE STATUSspodziewa się zobaczyć database namepo FROMi 'table name pattern'po LIKE.
x-yuri
2
ponieważ pamięć podręczna jest używana do pobierania danych z information_schema.tables, to rozwiązanie nie działa już dla mysql 8.
Bruno,
15
To zwróci wartość automatycznego przyrostu dla bazy danych MySQL, a ja nie sprawdzałem tego z innymi bazami danych. Pamiętaj, że jeśli używasz innej bazy danych, składnia zapytania może być inna.
SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema ='your_database_name';SELECT AUTO_INCREMENT
FROM information_schema.tables
WHERE table_name ='your_table_name'and table_schema =database();
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_name = 'twoja_nazwa_tabeli' i table_schema = 'twoja_nazwa_bazy_danych';
LJay
10
Najlepsza odpowiedź wykorzystuje PHP MySQL_ jako rozwiązanie, pomyślałem, że udostępnię zaktualizowane rozwiązanie PHP MySQLi_ , aby to osiągnąć. W tym przykładzie nie ma wyjścia błędu!
$db = new mysqli('localhost','user','pass','database');$sql ="SHOW TABLE STATUS LIKE 'table'";$result=$db->query($sql);$row=$result->fetch_assoc();
echo $row['Auto_increment'];
Pamiętaj, że w przypadku pierwszej metody, jeśli rekord o najwyższym identyfikatorze zostanie usunięty, utworzysz nowy rekord z identyfikatorem, który poprzednio miał porzucony.
Tom Jenkinson
a jeśli poprzedni klucz był używany w innych tabelach i nadal jest tam przechowywany, możesz skończyć z bardzo dziwną magią
Tebe
pierwszy zwraca zły identyfikator, jeśli upuścisz ostatnio wstawiony rekord,
Ali Parsa,
6
Rozwiązanie:
CREATETRIGGER`IdTrigger` BEFORE INSERTON`payments`FOR EACH ROWBEGINSELECT AUTO_INCREMENT Into@xId
FROM information_schema.tables
WHERE
Table_SCHEMA ="DataBaseName"AND
table_name ="payments";SET NEW.`payment_code`= CONCAT("sahf4d2fdd45",@xId);END;
Aktualizacja payment_codew after insertwyzwalaczu wydaje się najlepszą opcją.
binaryLV
3
Nie możesz używać identyfikatora podczas wstawiania, ani go nie potrzebujesz. MySQL nawet nie zna identyfikatora podczas wstawiania tego rekordu. Możesz po prostu zapisać "sahf4d2fdd45"w payment_codetabeli i użyć idipayment_code później.
Jeśli naprawdę potrzebujesz, aby kod payment_code zawierał identyfikator, ZAKTUALIZUJ wiersz po wstawce, aby dodać identyfikator.
+1 Aby było to trochę bardziej wyraźne: jeśli pobierzesz „najnowszą” wartość z kolumny, gwarantuje się, że będzie ona najnowszą wartością dokładnie w momencie jej pobrania. Może to nie być ostatnia wartość, gdy zaczniesz używać tej wartości w kolejnej wkładce. W przypadku kolumny z automatycznym zwiększaniem zawsze istnieje szansa, że między momentem pobrania identyfikatora a wstawieniem go w innym miejscu została dodana inna wartość. Jeśli odwołujesz się do wiersza, który właśnie wstawiłeś, użycie LAST_INSERT_ID () jest w porządku. Jeśli chcesz zapewnić unikalną wartość, tak nie jest.
Mike,
@cularis, MySQL zna następny identyfikator auto_increment, jest wymieniony w information_schema.tablestabeli.
Johan,
1
@faressoft: Jeśli chodzi o to, aby kod płatności składał się z unikalnego ciągu znaków oraz identyfikatora wiersza zawierającego ten kod płatności, po prostu połącz te dwa elementy podczas pobierania wiersza - za pomocą znaku SELECT ... CONCAT(payment_code, id)lub w kodzie aplikacji. Możesz nawet zawinąć SELECTw a VIEW, aby zawsze zwracać właściwą wartość, bez martwienia się o CONCAT w każdym SELECT z Twojej aplikacji.
Mike,
3
Do czego potrzebny jest następny przyrostowy identyfikator?
MySQL dopuszcza tylko jedno pole autoinkrementacji na tabelę i musi być również kluczem podstawowym, aby zagwarantować unikalność.
Zwróć uwagę, że kiedy otrzymasz następny identyfikator insertu, może on nie być dostępny, gdy go używasz, ponieważ wartość, którą posiadasz, mieści się tylko w zakresie tej transakcji. Dlatego w zależności od obciążenia bazy danych ta wartość może być już wykorzystana w momencie nadejścia następnego żądania.
Sugerowałbym, abyś przejrzał swój projekt, aby upewnić się, że nie musisz wiedzieć, która wartość automatycznego przyrostu ma zostać przypisana jako następna
Nie jest dobrym pomysłem zakładanie rodzaju aplikacji, która wymaga identyfikatora. Istnieją aplikacje, takie jak ta, nad którą obecnie pracuję, które wymagają kolejnego przyrostowego identyfikatora, a pobrana wartość nie jest zagrożona przypisaniem do innego skryptu.
JG Estiot
3
Proponuję przemyśleć to, co robisz. Nigdy nie doświadczyłem ani jednego przypadku użycia, w którym ta specjalna wiedza byłaby wymagana. Następny identyfikator to bardzo szczególny szczegół implementacji i nie liczyłbym na to, że jest bezpieczny dla ACID.
Wykonaj jedną prostą transakcję, która zaktualizuje wstawiony wiersz o ostatni identyfikator:
BEGIN;INSERTINTO payments (date, item, method)VALUES(NOW(),'1 Month','paypal');UPDATE payments SET payment_code = CONCAT("sahf4d2fdd45", LAST_INSERT_ID())WHERE id = LAST_INSERT_ID();COMMIT;
Mogę powiedzieć jeden taki przypadek użycia, próbuję zdiagnozować problem produkcyjny, więc muszę się dowiedzieć, czy ostatni wiersz w tabeli jest tak naprawdę ostatnim wierszem, czy też został dodany po tym, który jakoś został usunięty, tabela zawiera pole auto_increment, więc znajdując te informacje, mogę stwierdzić, czy wiersz został usunięty, czy nigdy nie został dodany.
Usman
1
To może zadziałać dla Ciebie, ale nie polegałbym na tym, ponieważ nie sądzę, że masz na to jakąkolwiek gwarancję: dev.mysql.com/doc/refman/8.0/en/example-auto-increment.html ” gdy kolumna AUTO_INCREMENT jest częścią indeksu z wieloma kolumnami), wartości AUTO_INCREMENT są ponownie używane, jeśli usuniesz wiersz z największą wartością AUTO_INCREMENT w dowolnej grupie. "
Markus Malkusch,
Dzięki, przydatne informacje, również zgodnie z udostępnionym linkiem auto_increment można zresetować ręcznie, wprowadzając liczbę, więc tak nie jest wiarygodne.
Usman
2
Musisz połączyć się z MySQL i wybrać bazę danych, zanim będziesz mógł to zrobić
$table_name ="myTable";$query = mysql_query("SHOW TABLE STATUS WHERE name='$table_name'");$row= mysql_fetch_array($query);$next_inc_value =$row["AUTO_INCREMENT"];
użyj „mysql_insert_id ()”. mysql_insert_id () działa na ostatnio wykonanym zapytaniu, pamiętaj, aby wywołać mysql_insert_id () natychmiast po zapytaniu, które generuje wartość.
Poniżej przykład zastosowania:
<?php
$link = mysql_connect('localhost','username','password');if(!$link){
die('Could not connect: '. mysql_error());}
mysql_select_db('mydb');
mysql_query("INSERT INTO mytable VALUES('','value')");
printf("Last inserted record has id %d\n", mysql_insert_id());?>
Ja również zgadzam się, że jest to najprostsze podejście. Nie jestem pewien, dlaczego zostałeś przegłosowany, ale zrównoważę głosem za.
powtórzona
Nie wspomniałem o konieczności transakcji, jeśli nie zapakujesz jej w transakcję, ten kod jest kiepski, jak tylko spełnia rzeczywiste ładowanie.
Tebe
1
Co jeśli ostatni wiersz został usunięty? Czy wiele ostatnich wierszy zostało usuniętych?
Liam W
Zwolnione klucze nie są używane, chyba że wyraźnie to określisz
Tebe
1
używając odpowiedzi ravi404:
CREATEFUNCTION`getAutoincrementalNextVal`(`TableName` VARCHAR(50))
RETURNS BIGINT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''BEGINDECLARE Value BIGINT;SELECT
AUTO_INCREMENT INTO Value
FROM
information_schema.tables
WHERE
table_name = TableName AND
table_schema =DATABASE();RETURN Value;END
używając w zapytaniu wstawiającym, aby utworzyć skrót SHA1. dawny.:
Czy to zawsze działa? Czy są warunki wyścigu, jeśli w tym samym czasie zdarzają się dwie wkładki?
Jmons
0
Poprawa @ ravi404, w przypadku gdy przesunięcie autoincrement NIE JEST 1:
SELECT(`auto_increment`-1)+ IFNULL(@@auto_increment_offset,1)FROM INFORMATION_SCHEMA.TABLES
WHERE table_name = your_table_name
AND table_schema =DATABASE();
( auto_increment-1): silnik db wydaje się zawsze uwzględniać przesunięcie o 1. Więc musisz porzucić to założenie, a następnie dodać opcjonalną wartość @@ auto_increment_offset lub domyślnie 1: IFNULL (@@ auto_increment_offset, 1)
$auto_inc_db = mysql_query("SELECT * FROM my_table_name ORDER BY id ASC ");while($auto_inc_result = mysql_fetch_array($auto_inc_db)){$last_id =$auto_inc_result['id'];}$next_id =($last_id+1);
echo $next_id;//this is the new id,if auto increment ison
auto_increment
kolumnyOdpowiedzi:
Użyj
LAST_INSERT_ID()
z zapytania SQL.Lub
Możesz również użyć,
mysql_insert_id()
aby uzyskać go za pomocą PHP.źródło
LAST_INSERT_ID()
.mysqli_insert_id
Możesz użyć
lub jeśli nie chcesz używać schematu information_schema, możesz użyć tego
źródło
TABLES.AUTO_INCREMENT
jest buforowany dev.mysql.com/doc/refman/8.0/en/… . Blog MySQL również zawiera kilka postów na ten temat, ale zmienna systemowa, o której wspominają, wydaje się przestarzała: mysqlserverteam.com/… mysqlserverteam.com/…Możesz uzyskać następną wartość automatycznego zwiększania, wykonując:
Należy pamiętać, że należy nie używać tego zmienić tabelę, należy użyć kolumny auto_increment to zrobić automatycznie zamiast.
Problem polega na tym, że
last_insert_id()
jest to retrospektywne i dzięki temu można je zagwarantować w ramach bieżącego połączenia.To dziecko jest perspektywiczne i dlatego nie jest wyjątkowe pod względem połączenia i nie można na nim polegać.
To działałoby tylko w przypadku jednej bazy danych połączeń, ale bazy danych z jednym połączeniem mają dziś zwyczaj stawania się jutro wieloma bazami danych połączeń.
Widzieć:
SHOW TABLE STATUS
źródło
insert into table_name (field1, field2) select 'constant', auto_increment from information_schema.tables where table_name = 'table_name'
?after insert
last_insert_id()
UPDATE
gdybym też. Ale wolałbym po prostu połączyć te dwie rzeczy w czasie wyświetlania i zaoszczędzić wszystkich kłopotów.SHOW TABLE STATUS
spodziewa się zobaczyćdatabase name
poFROM
i'table name pattern'
poLIKE
.To zwróci wartość automatycznego przyrostu dla bazy danych MySQL, a ja nie sprawdzałem tego z innymi bazami danych. Pamiętaj, że jeśli używasz innej bazy danych, składnia zapytania może być inna.
źródło
Najlepsza odpowiedź wykorzystuje PHP MySQL_ jako rozwiązanie, pomyślałem, że udostępnię zaktualizowane rozwiązanie PHP MySQLi_ , aby to osiągnąć. W tym przykładzie nie ma wyjścia błędu!
Wyrzuca następny automatyczny przyrost w tabeli.
źródło
W PHP możesz spróbować tego:
LUB
źródło
Rozwiązanie:
„DataBaseName” to nazwa naszej bazy danych
źródło
Wystarczy proste zapytanie
SHOW TABLE STATUS LIKE 'table_name'
źródło
Możesz użyć wyzwalacza mysql
źródło
payment_code
wafter insert
wyzwalaczu wydaje się najlepszą opcją.Nie możesz używać identyfikatora podczas wstawiania, ani go nie potrzebujesz. MySQL nawet nie zna identyfikatora podczas wstawiania tego rekordu. Możesz po prostu zapisać
"sahf4d2fdd45"
wpayment_code
tabeli i użyćid
ipayment_code
później.Jeśli naprawdę potrzebujesz, aby kod payment_code zawierał identyfikator, ZAKTUALIZUJ wiersz po wstawce, aby dodać identyfikator.
źródło
information_schema.tables
tabeli.SELECT ... CONCAT(payment_code, id)
lub w kodzie aplikacji. Możesz nawet zawinąćSELECT
w aVIEW
, aby zawsze zwracać właściwą wartość, bez martwienia się o CONCAT w każdym SELECT z Twojej aplikacji.Do czego potrzebny jest następny przyrostowy identyfikator?
MySQL dopuszcza tylko jedno pole autoinkrementacji na tabelę i musi być również kluczem podstawowym, aby zagwarantować unikalność.
Zwróć uwagę, że kiedy otrzymasz następny identyfikator insertu, może on nie być dostępny, gdy go używasz, ponieważ wartość, którą posiadasz, mieści się tylko w zakresie tej transakcji. Dlatego w zależności od obciążenia bazy danych ta wartość może być już wykorzystana w momencie nadejścia następnego żądania.
Sugerowałbym, abyś przejrzał swój projekt, aby upewnić się, że nie musisz wiedzieć, która wartość automatycznego przyrostu ma zostać przypisana jako następna
źródło
Proponuję przemyśleć to, co robisz. Nigdy nie doświadczyłem ani jednego przypadku użycia, w którym ta specjalna wiedza byłaby wymagana. Następny identyfikator to bardzo szczególny szczegół implementacji i nie liczyłbym na to, że jest bezpieczny dla ACID.
Wykonaj jedną prostą transakcję, która zaktualizuje wstawiony wiersz o ostatni identyfikator:
źródło
Musisz połączyć się z MySQL i wybrać bazę danych, zanim będziesz mógł to zrobić
źródło
użyj „mysql_insert_id ()”. mysql_insert_id () działa na ostatnio wykonanym zapytaniu, pamiętaj, aby wywołać mysql_insert_id () natychmiast po zapytaniu, które generuje wartość.
Poniżej przykład zastosowania:
Mam nadzieję, że powyższy przykład się przyda.
źródło
Otóż to :)
źródło
Chociaż wątpię w jego produktywność, ale jest w 100% niezawodny
źródło
używając odpowiedzi ravi404:
używając w zapytaniu wstawiającym, aby utworzyć skrót SHA1. dawny.:
źródło
Poprawa @ ravi404, w przypadku gdy przesunięcie autoincrement NIE JEST 1:
(
auto_increment
-1): silnik db wydaje się zawsze uwzględniać przesunięcie o 1. Więc musisz porzucić to założenie, a następnie dodać opcjonalną wartość @@ auto_increment_offset lub domyślnie 1: IFNULL (@@ auto_increment_offset, 1)źródło
U mnie działa i wygląda prosto:
źródło
$last_id
powtarzalne przypisywanie, kiedy możesz po prostuDESC
. Twójwhile
blok wykonał mnóstwo bezużytecznej pracy.Jeśli nie zwrócisz poprawnego AUTO_INCREMENT, spróbuj:
Ta czysta pamięć podręczna dla tabeli w BD
źródło