MariaDB: Nextval als Select-Kriterium

habe ich kurzerhand PostgreSQL installiert und den ursprünglichen Ansatz getestet: Hier hat er einwandfrei funktioniert.
Sehr interessant, erschließt sich für mich nicht, sollte eine Prinzipfrage sein, nicht eine Herstellerfrage.

Danke fürs Feedback und gleich die Frage, ob Du den "ursprünglichen Ansatz" posten kannst (sofern er nicht oben genau so aufgeführt ist)?
Ach und davon ab ist die Entscheidung zum Wechsel sicher eine gute, grundsätzlich.
 
Werbung:
Also, da stimmt was nicht !

In PostgreSQL ist lastval() pro Sitzung (Session) und nicht global. Das bedeutet, dass lastval() den zuletzt generierten Wert für eine Sequenz zurückgibt, die innerhalb derselben Sitzung verwendet wurde. Es gibt keine Konflikte zwischen verschiedenen Sitzungen; jede Sitzung erhält ihren eigenen Kontext für die Sequenzen.

Code:
CREATE SEQUENCE my_sequence START 1;



-- connection #1

SELECT nextval('my_sequence');  -- Gibt 1 zurück
SELECT nextval('my_sequence');  -- Gibt 2 zurück
SELECT lastval();               -- Gibt 2 zurück


-- connection #2

SELECT nextval('my_sequence');  -- Gibt 3 zurück
SELECT lastval();               -- Gibt 3 zurück




-- connection #1

SELECT lastval();  -- Gibt 2 zurück (Sitzung 1-Kontext)

-- connection #2

SELECT lastval();  -- Gibt 3 zurück (Sitzung 2-Kontext)


Fazit​

  • nextval() ist global und erhöht den Sequenzwert unabhängig von der Sitzung.
  • lastval() ist sitzungsbezogen und gibt den zuletzt generierten Sequenzwert innerhalb der aktuellen Sitzung zurück.
 
Was denn nicht?

Genau wie Du es beschreibst, soll(te) es sein, auch bei anderen Herstellern.

So wie ich den Benutzer verstanden hatte wollte er einen globalen Zähler haben, damit mehrere Clients immer das letzte Ereignis bekommen, das er in ein Ringbuffer (Innodb) schreibt also zb. lastval() % 512. Und dies würde ja so nicht gehen, denn
er bekommt da nur je Client die zuletzt geholte Nr.


In MariaDB kann man diesen Wert aber über das Info Schema bekommen.


Die Funktionalität ist aber bei PG und MariaDB komplett gleich. Nur bei MySQL gibt es dies (noch) nict
 
Code:
``` 
select version();
```
| version |
|:--------|
| PostgreSQL 16.0 (Debian 16.0-1.pgdg120+1) on x86\_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit |
> ``` status
> SELECT 1
> ```

``` 
CREATE TABLE public.treadings03 (
    rid integer,
    d01 double precision,
    dtn timestamp without time zone
);
```
> ``` status
> CREATE TABLE
> ```

``` 
INSERT INTO public.treadings03 VALUES (1, 0.355, '2024-07-08 15:18:53.689');
INSERT INTO public.treadings03 VALUES (2, 0.019, '2024-07-08 15:18:53.693');
INSERT INTO public.treadings03 VALUES (3, 0.726, '2024-07-08 15:18:53.697');
INSERT INTO public.treadings03 VALUES (4, 0.488, '2024-07-08 15:18:53.701');
INSERT INTO public.treadings03 VALUES (5, 0.213, '2024-07-08 15:18:53.705');
```
> ``` status
> INSERT 0 1
> ```

> ``` status
> INSERT 0 1
> ```

> ``` status
> INSERT 0 1
> ```

> ``` status
> INSERT 0 1
> ```

> ``` status
> INSERT 0 1
> ```

``` 
select * from public.treadings03
```
| rid | d01 | dtn |
|----:|:----|:----|
| 1 | 0.355 | 2024-07-08 15:18:53.689 |
| 2 | 0.019 | 2024-07-08 15:18:53.693 |
| 3 | 0.726 | 2024-07-08 15:18:53.697 |
| 4 | 0.488 | 2024-07-08 15:18:53.701 |
| 5 | 0.213 | 2024-07-08 15:18:53.705 |
> ``` status
> SELECT 5
> ```

``` 
CREATE UNLOGGED SEQUENCE IF NOT EXISTS public.seq03
    CYCLE
    INCREMENT 1
    START 1
    MINVALUE 1
    MAXVALUE 5
    CACHE 1;
```
> ``` status
> CREATE SEQUENCE
> ```

``` 
UPDATE treadings03 SET D01=0.001, DTN=now() WHERE treadings03.RID=(select (nextval('seq03')))
```
> ``` status
> UPDATE 1
> ```

``` 
select * from public.treadings03
```
| rid | d01 | dtn |
|----:|:----|:----|
| 2 | 0.019 | 2024-07-08 15:18:53.693 |
| 3 | 0.726 | 2024-07-08 15:18:53.697 |
| 4 | 0.488 | 2024-07-08 15:18:53.701 |
| 5 | 0.213 | 2024-07-08 15:18:53.705 |
| 1 | 0.001 | 2024-07-10 09:33:05.995822 |
> ``` status
> SELECT 5
> ```

``` 
UPDATE treadings03 SET D01=0.002, DTN=now() WHERE treadings03.RID=(select (nextval('seq03')))
```
> ``` status
> UPDATE 1
> ```

``` 
select * from public.treadings03
```
| rid | d01 | dtn |
|----:|:----|:----|
| 3 | 0.726 | 2024-07-08 15:18:53.697 |
| 4 | 0.488 | 2024-07-08 15:18:53.701 |
| 5 | 0.213 | 2024-07-08 15:18:53.705 |
| 1 | 0.001 | 2024-07-10 09:33:05.995822 |
| 2 | 0.002 | 2024-07-10 09:33:06.003428 |
> ``` status
> SELECT 5
> ```



So, ich habe das jetzt mal verschlankt, damit das Prinzip besser ersichtlich wird. Genau so war es von Anfang an gedacht und genau so funktioniert es auch in PostgreSQL.

MariaDB hat hingegen bei jedem einzelnen Update-Aufruf ALLE Datensätze ge-updated (heißt es ge-updated oder upgedated? 🤔). Dieses Verhalten ist für mich nicht nachvollziehbar. Entweder hätte es nur einen Datensatz aktualisieren dürfen, oder es hätte in einer Endlosschleife verweilen müssen. Den ganzen MariaDB-Versuch habe ich inzwischen gelöscht.

Ich stelle jetzt also die These in den Raum, dass PostgreSQL eher zu meiner Logik passt, als es bei MariaDB der Fall ist.

Nun denn, die Würfel sind gefallen.
 
Zuletzt bearbeitet von einem Moderator:
Werbung:
Zurück
Oben