Mam bazę danych z tabelą rekordów dziennika, która wygląda tak:

+-----------+------------------------+--------+
| Timestamp | Symbol_name            | Status |
+-----------+------------------------+--------+
|         1 | Group2                 |      1 |
|         2 | Group1-Device3-Signal1 |      1 |
|         3 | Group2-Device1-Signa13 |      0 |
+-----------+------------------------+--------+

Gdzie Timestamp to double, Symbol_name to varchar, a Status to int.

Rekordy logów zawierające powyższe dane będą wstawiane do tabeli w czasie rzeczywistym, a mój kod klienta ma za zadanie odpytywać te rekordy i je analizować. Problem, który mam teraz, to odczytywanie unikalnego rekordu każdego zapytania. Obecnie posiadam taką funkcję:

/* Called every 1000 ms (1 second). */
gboolean app_models_timed_query(gpointer data) {
    FwApp *app = data;

    char query[APP_MAXIMUM_STRING_CHARS];

    strncpy(query, "SELECT * FROM ", APP_MAXIMUM_STRING_CHARS);
    strncat(query, app->query_db_table_name, APP_MAXIMUM_STRING_CHARS);
    strncat(query, " WHERE Timestamp <> @lastSeenTimestamp AND Symbol_name <> @lastSeenSymbolName AND Status <> @lastSeenStatus;", APP_MAXIMUM_STRING_CHARS);

    if (mysql_query(app->query_db_con, query))
    {
        printf("Unable to retrieve data from query table.\n");
        return TRUE;
    }

    MYSQL_RES *result = mysql_store_result(app->query_db_con);

    if (result == NULL) return TRUE;

    /* Analyze the resulting row(s) here. */

    /* How to set @lastSeenTimestamp, @lastSeenSymbolName and @lastSeenStatus here? */

    return TRUE;
}

Funkcja jest wywoływana co sekundę, a w niej wysyłam zapytanie do bazy danych za pomocą następującej instrukcji:

SELECT * FROM table1 WHERE Timestamp <> @lastSeenTimestamp AND Symbol_name <> @lastSeenSymbolName AND Status <> @lastSeenStatus;

Żadne dwa rekordy nigdy nie będą dokładnie takie same, ale mogą mieć ten sam znacznik czasu, status lub nazwę symbolu.

Zauważ, że zanim włączę wywoływanie app_models_timed_query co sekundę, ustawiłem zmienne zdefiniowane przez użytkownika w następujący sposób:

SET @lastSeenTimestamp = -1, @lastSeenSymbolName = '', @lastSeenStatus = 0;

A ponieważ znaczniki czasu nigdy nie będą ujemne, przy pierwszym wywołaniu app_models_timed_query pierwszy wiersz będzie w wyniku zapytania.

Jednak moje pytanie brzmi, jak ustawić zmienne zdefiniowane przez użytkownika w ostatnim wierszu wyniku mojego zapytania. Chcę również wiedzieć, czy istnieje lepszy sposób na odczytywanie tylko nowo wstawionych wierszy za każdym razem, gdy wywoływane jest app_models_timed_query.

Wielkie dzięki, Vikas

1
Vikas M 22 listopad 2018, 00:03

1 odpowiedź

Najlepsza odpowiedź

Powinieneś używać kolejki komunikatów takiej jak RabbitMQ dla tego rodzaju aplikacji. Kolejki komunikatów mają interfejs API powiązany z pobieraniem ze szczytu kolejki. Nawet jeśli przechowujesz główne dane w MySQL, możesz użyć kolejki wiadomości dla klucza podstawowego. Dzięki temu wyborowi odpowiedniej infrastruktury Twoja aplikacja nie musi zachowywać stanu.

1
danblack 22 listopad 2018, 01:58
Dziękuję za radę. Sprawdziłem RabbitMQ i nie mogłem znaleźć przykładów dla MySQL. Czy mógłbyś opublikować, jak mogę skonfigurować proces kolejkowania wiadomości?
 – 
Vikas M
22 listopad 2018, 03:52
2
Gdy aplikacja logująca się do tabeli wstawia wiersz MySQL, wstawia również PK (identyfikator automatycznego przyrostu, jeśli go nie masz) w skonfigurowanej kolejce. Twoja aplikacja jako konsument pobiera PK z kolejki. Zacznij od podstawowego przykładu Hello World: rabbitmq.com/getstarted.html
 – 
danblack
22 listopad 2018, 04:04
Ach. Bardzo dziękuję.
 – 
Vikas M
22 listopad 2018, 04:14