Miliony rekordów w bazie MySQL

Miliony rekordów w bazie MySQL

Wątek przeniesiony 2022-08-30 21:08 z Inżynieria oprogramowania przez Riddle.

25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0

Jak sobie radzić z zapytaniami, gdy tabela liczy już co najmniej milion, a nawet parę rekordów?
Czy jest się wtedy skazanym na sekundowe, paru-sekundowe oczekiwanie na wykonanie zapytania?

Co jeśli po roku tych rekordów będzie z 20 milionów?

Czy w tak pojemnej tabeli przechowywać wszystkie rekordy czy może tylko ostatnie z 30 dni? A resztę trzymać w jakiejś innej?

Też mnie ciekawi jak są strony, które mają ogrom statystyk (np. ceny kryptowalut z ostatnich lat). Jak to jest zrobione, że jest tak dużo danych i to się tak szybko ładuje?

tomepaw
  • Rejestracja:ponad 14 lat
  • Ostatnio:ponad rok
  • Lokalizacja:Lublin
  • Postów:218
4

Optymalizacja zapytań, dodanie indeksów, cachowanie.

25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0

A jeśli zapytania są tak proste, że nie ma co optymalizować, indeksy są dodane do pól po których rekordy są wyszukiwane a cachowanie trochę nie pasuje, ponieważ dane co 5 minut są aktualizowane?

ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1

@2solaris5:

Ukrywasz rzeczywiste zagadnienie, czyli kręcisz.

Czy jest się wtedy skazanym na sekundowe, paru-sekundowe oczekiwanie na wykonanie zapytania?

Co jest klientem bazy danych? Soluszyn desktopowe? Wieloużytkownikowe webowe? W jakim języku ?
Mozna robić coś w modelu 'async' ale to zupełnie inna opowieść i nie ma nic wspólnego z bazami danych

Też mnie ciekawi jak są strony, które mają ogrom statystyk (np. ceny kryptowalut z ostatnich lat). Jak to jest zrobione, że jest tak dużo danych i to się tak szybko ładuje?

Rozległem archiwa historyczne (nie podlegające zmianom) prawie nigdy nie trzyma się w bazach SQL, taka zmiana kontekstu pozbawia je zalet.
Największe soluszyny na pewno się rozprasza (i współczesne NoSQLe są bardziej podatne na rozpraszanie - SQL kocha integralność)

Czy w tak pojemnej tabeli przechowywać wszystkie rekordy czy może tylko ostatnie z 30 dni? A resztę trzymać w jakiejś innej?

I mieć inne raporty dla FV z ostatnich 30 dni, inne dla starszych ? Przerażające constraintsy na klucze obce ? Brr, strach nawet pomyśleć ...
To niemal zawsze jest zła pokusa. Pozorne rozwiązanie 1go problemu, które generuje 20 innych


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
edytowany 3x, ostatnio: ZrobieDobrze
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1

@2solaris5:

Właśnie zerknąłem:
11mln w tabeli , drugie miejsce 1.3 mln - to mała baza, pięknie gania na limitowanych Expressie 1.5GB RAM.

26mln / 3mln - baza najwyżej średnia, dostaje chyba 8GB RAM

Profesjonalnie zaprojektowane, indeksy, dopóki nie udupcyć kwerendą z like % nie widać specjalnych problemów.


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
Michał Kuliński
  • Rejestracja:prawie 8 lat
  • Ostatnio:9 miesięcy
  • Postów:74
25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0

Niesamowite, naprawdę. Może mi Laravel Telescope to wszystko spowalnia też trochę. Spróbuję go wyłączyć dla niektórych jobsów. Bo właśnie zauważyłem, że w ciągu 10 dni stworzyło się logów na ponad 20 GB.

Swoją drogą - czy stosujesz jakąś specjalną konfigurację mysql czy zostałeś przy domyślnej?
I ile ramu przydzielić do wykorzystania serwerowi mysql?
W ogóle ile ramu posiadać na serwerze do takich dość dużych zbiorów?

ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1

@2solaris5:

Logowanie do SQL to uroda (dość mało inteligenta, żeby nie kląć) światka PHP.
To trochę się bierze z tego, ze na bieda-hostingu jest jednym z niewielu dostępnych w czasie rzeczywistym (logi z /var/log są dostępne np po północy )

Zobaczysz temat w szerszym horyzoncie, jak pogrzebiesz w YT u ewangelizatorów dużych projektów Javy. Są naprawdę piękne rozwiązania.

Być może w PHP / Lavarelu jakieś profesjonalne silniki logowania są dostępne, ale na pewno w tym środowisku się o tym nie rozmawia


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
katakrowa
Powiedział co wiedział...
ZD
  • Rejestracja:około 3 lata
  • Ostatnio:ponad rok
  • Postów:2310
1
2solaris5 napisał(a):

Swoją drogą - czy stosujesz jakąś specjalną konfigurację mysql czy zostałeś przy domyślnej?
I ile ramu przydzielić do wykorzystania serwerowi mysql?

Nie czuję się pro adminem bazowym. Ale zarówno MySQL jak i MariaDb maja wiodące artykuły nt optymalizacji, powszechnie znane. Stosuję 3-4 elementy z tych artykułów.
"Jak zawiodą wszystkie środki przeczytać dokumentację" ?

RAM ... to zależy, ile klient ma na serwery itd... dawniej (=20 lat temu) się cieszyliśmy, jak RAMu było na 15% bazy, dziś modne by było całą zmieścić w RAM.


If you put a million monkeys at a million keyboards, one of them will eventually write a Java program - the rest of them will write Perl
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 dni
  • Postów:3277
2

Jeżeli przy kilku milionach rekordów masz problem z czasem odpowiedzi, to coś jest zrypane - struktura, indeksy, zapytanie, statystyki serwera. Sprawdzałeś plan zapytania, czy "patrzyłem w kod i jest dobrze"? Zmieniłeś w tym co się łączy do bazy poziom izolacji na coś czego potrzebujesz, czy jedziesz na defaulcie (repeatable read)?
Jeżeli używasz bazy danych SQL tylko po to, żeby ją co 5 minut wypełnić dodatkowymi danymi i żeby każdy request pobierał sobie te ostatnie 5 minut danych (być może agregując je sobie w jakiś sposób), to używasz złego narzędzia.

katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
2

Generalnie dopóki nie sprecyzujesz dokładnie problemu to dyskutowanie o tym czy się da czy się nie da uzyskiwać odpowiedzi w czasie < 1 sek. jest bez sensu.
Nie znamy struktury ani rodzaju zapytań o jakich piszesz ale poteoretyzować można...

2solaris5 napisał(a):

A jeśli zapytania są tak proste, że nie ma co optymalizować, indeksy są dodane do pól po których rekordy są wyszukiwane a cachowanie trochę nie pasuje, ponieważ dane co 5 minut są aktualizowane?

Najprawdopodobniej to znaczy, ze baza jest źle zaprojektowana robisz wyszukiwanie po stringach, brakuje kluczy itp... Dopóki nie przeszukujesz dużych pól tekstowych zwykłym "like" to kilka milionów rekordów nawet dla MySQL nie jest problemem i odpowiedzi powinny trwać ułamek sekundy.

Czy jest się wtedy skazanym na sekundowe, paru-sekundowe oczekiwanie na wykonanie zapytania?

Nie.

Co jeśli po roku tych rekordów będzie z 20 milionów?

To znaczy, ze po 5 latach ich może być 100 milionów i nadal nie powinno być problemu.

Czy w tak pojemnej tabeli przechowywać wszystkie rekordy czy może tylko ostatnie z 30 dni? A resztę trzymać w jakiejś innej?

A to zależy co chcesz osiągnąć, jakie są Twoje dane i jakie są cele projektu.

Też mnie ciekawi jak są strony, które mają ogrom statystyk (np. ceny kryptowalut z ostatnich lat). Jak to jest zrobione, że jest tak dużo danych i to się tak szybko ładuje?

Jeśli działa to sprawnie to znaczy, że są zrobione "z głową"" i w sposób przemyślany. Nie ma jednej ogólnej dobrej rady na wszelkie zagadnienia związane z dużą ilością rekordów.
Rekord rekordowi nie równy :-)

Mam bazę do której wpada mi po 400 rekordów na minutę (dziś) w szczycie sezonu dochodzi do 2000 ale na potrzeby prezentacji co 3 minuty tworzę agregaty które lecą do Elasticseracha.
Czym innym jest ujęcie statystyczne na potrzeby prezentacji a czym innym praca na ostatnich bieżących rekordach w celach analizy. Jednak korzystam z bazy często i zależy mi na tym żeby to śmigało. Dlatego w głównej tabeli mam same kolumny INT nawet adresy IP i domeny trzymam w osobnych tabelach a w głównej przeszukiwanej trzymam tylko klucze. Dzięki temu cała tabela jest dość mała i może sobie siedzieć w Cache (MySQL robi to sam). W chwili obecnej baza ma 3,6 miliona rekordów zajmuje niecały GB. Proste pytania na takiej tabeli to jakieś milisekundy:
screenshot-20220702121234.png

screenshot-20220702115501.png

W powyższym przypadku na swoje potrzeby nie potrzebuję wykonywać dalszych optymalizacji a nadal w ramach standardowego MySQL są dostępne opcje takie jak:

Gdyby była potrzeba to w dalszych etapach możemy skorzystać z dobrodziejst klastra: https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-innodb-cluster.html
lub replikacji bazy i loadbalancingu.


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0

Tak wygląda moja struktura tabeli.
Rekordy obecnie wybieram tylko po polach server_id i created_at.
Konfiguracja MariaDB jest domyślna, nic nie zmieniałem.
Zdarza się, że wybranie za pierwszym razem danych trwa od 0.5 do 3.2 sekund.
Kolejne pobrania tych samych danych trwają 100-300ms.

Na chwile obecną moje zapytania są proste w stylu. No i jakas data to zwykle 1 dzień wstecz.

I tak w ogóle czy string jako id jest wolniejszy?

Kopiuj
 SELECT * FROM room_statistics WHERE server_id = 5 AND created_at >= 'jakas data'
Kopiuj
         Schema::create('room_statistics', function (Blueprint $table) {
            $table->uuid('id')->primary();
            $table->foreignId('server_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
            $table->tinyInteger('status');
            $table->boolean('online');
            $table->integer('spoof')->default(false);
            $table->integer('players_1')->default(0);
            $table->integer('players_2')->default(0);
            $table->integer('players_3')->default(0);
            $table->integer('npcs')->default(0);
            $table->integer('monsters')->default(0);
            $table->integer('mounts')->default(0);
            $table->integer('interval')->default(0);
            $table->timestamps();

            $table->index('created_at');
        });
edytowany 3x, ostatnio: 2solaris5
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
1
2solaris5 napisał(a):

Rekordy obecnie wybieram tylko po polach server_id i created_at.

Czy masz założone indeksy na tych kolumnach?
Wykonaj w SQL komendę

Kopiuj
SHOW INDEX FROM `room_statistics`;

i wklej tu jej wynik.


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 1x, ostatnio: katakrowa
abrakadaber
abrakadaber
dodam tylko, że nie chodzi o dwa OSOBNE indeksy ale o JEDEN z OBYDWOMA polami
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 dni
  • Postów:3277
1

@2solaris5: Pokaż plan tego zapytania. Klucz obcy nie jest z automatu indeksem. wróć też planem zapytania explain analyze select * from server statistics...

katakrowa
To krok drugi :-) Ja obstawiam, że nie ma indeksów.
piotrpo
Nie wiem co robi ten kawałek PHP, a na MySQL też się nie znam, co właściwie robi to: $table->index('created_at');?
katakrowa
Nie mam pojęcia ale co by nie robił czego można się domyślić (pewnie tworzy indeks) to w jego przypadku i tak brakuje $table->index('server_id'); :-) To pewnie jakiś Laravel albo inny framework: https://laravel.com/docs/5.0/schema
25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0

screenshot-20220702131409.png

screenshot-20220702131458.png

Ogólnie chwilowo nie mam rekordów, bo postawiłem bazę od nowa.

katakrowa
Po co stawiałeś nową bazę? Wystarczyło dodać indeks w starej. Zmiana struktury nie wymaga stawiania bazy na nowo.
25
Mam kopię tej bazy, na razie chciałem zacząć wszystko na czysto, a nowe rekordy i tak szybko mi się zapełniają.
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
0
2solaris5 napisał(a):

Ogólnie chwilowo nie mam rekordów, bo postawiłem bazę od nowa.

Czyli wielka improwizacja :-)
Z kodu, który wkleiłeś wyżej wynika, że nie miałeś prawa mieć tego indeksu. Skąd zatem magicznie się pojawił 4 minuty temu?

Kopiuj
         Schema::create('room_statistics', function (Blueprint $table) {
            $table->uuid('id')->primary();
            $table->foreignId('server_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
            $table->tinyInteger('status');
            $table->boolean('online');
            $table->integer('spoof')->default(false);
            $table->integer('players_1')->default(0);
            $table->integer('players_2')->default(0);
            $table->integer('players_3')->default(0);
            $table->integer('npcs')->default(0);
            $table->integer('monsters')->default(0);
            $table->integer('mounts')->default(0);
            $table->integer('interval')->default(0);
            $table->timestamps();

            $table->index('created_at');
        });

Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 1x, ostatnio: katakrowa
25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0

Te 2 linijki ustawiają indeksy. Klucz obcy w laravelu automatycznie nadaje indeks.

Kopiuj
$table->foreignId('server_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
$table->index('created_at');
edytowany 2x, ostatnio: 2solaris5
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
1

A w jaki sposób mierzysz ten czas i czy przypadkiem to nie jest select * bez limitów? To mogłoby oznaczać, że to czas przesyłania danych a nie wykonywania zapytania.
Strasznie skąpisz informacji i każesz się strasznie dużo domyślać.

  1. Wrzuć gdzieś strukturę tej bazy najlepiej dumpa,
  2. Napisz jakie konkretnie zapytanie SQL zadajesz, które Twoim zdaniem wykonuje się zbyt długo,
  3. Napisz czy serwer masz lokalnie czy zdalny,

Daj szansę sobie pomóc.

2solaris5 napisał(a):

Na chwile obecną moje zapytania są proste w stylu. No i jakas data to zwykle 1 dzień wstecz.
I tak w ogóle czy string jako id jest wolniejszy?

String jako id jest wolniejszy jeśli nie ma indeksu. Z indeksem ta różnica jest dużo mniejsza.


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 1x, ostatnio: katakrowa
ZD
stronę wcześnie w tym wątku o niczym pisałem - ze kolega kręci.
25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
0
Kopiuj
--
-- Table structure for table `room_statistics`
--

DROP TABLE IF EXISTS `room_statistics`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `room_statistics` (
  `id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
  `server_id` bigint(20) unsigned NOT NULL,
  `status` tinyint(4) NOT NULL,
  `online` tinyint(1) NOT NULL,
  `spoof` int(11) NOT NULL DEFAULT 0,
  `players_1` int(11) NOT NULL DEFAULT 0,
  `players_2` int(11) NOT NULL DEFAULT 0,
  `players_3` int(11) NOT NULL DEFAULT 0,
  `npcs` int(11) NOT NULL DEFAULT 0,
  `monsters` int(11) NOT NULL DEFAULT 0,
  `mounts` int(11) NOT NULL DEFAULT 0,
  `interval` int(11) NOT NULL DEFAULT 0,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `room_statistics_server_id_foreign` (`server_id`),
  KEY `room_statistics_created_at_index` (`created_at`),
  CONSTRAINT `room_statistics_server_id_foreign` FOREIGN KEY (`server_id`) REFERENCES `servers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
  1. Potrafi (bez mysql cache) za pierwszym razem zwracać rekordy nawet do 3.2 sekundy. Później przez chwile jest to normalna wartość. 100-300ms. Jak w tabeli jest ponad milion rekordów.
Kopiuj
SELECT * FROM room_statistics WHERE server_id = 5 AND created_at >= 'jakas data'
  1. To VPS. 4 rdzenie, 8 gb ramu, dysk nvme
edytowany 1x, ostatnio: 2solaris5
ZD
O .,.. wiec jednak VPS ... jak wątek osiągnie siedem stron zaczniemy coś wiedzieć ....
katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
1

Naprawdę nie umiesz wrzucić wszystkiego?
Napisałem Wrzuć gdzieś strukturę tej bazy
Struktura bazy to nie jedna tabela.
Co ma nam dać jedna tabela?

Na tej konfiguracji VPS powinno zapierniczać aż miło! Zatem COŚ ROBISZ ŹLE!


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
edytowany 3x, ostatnio: cerrato
piotrpo
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 dni
  • Postów:3277
1

@katakrowa: Myślę, że przy tym zapytaniu nie ma co patrzeć na resztę bazy danych.

@2solaris5: Wrzuć plan zapytania (EXPLAIN). Ciężko się domyślić co sobie optymalizator SQL wymyślił. Czy na tej tabeli jest jedynie ruch insert+select, czy robisz jakieś update/delete?

katakrowa
  • Rejestracja:około 10 lat
  • Ostatnio:około 2 lata
  • Lokalizacja:Chorzów
  • Postów:1670
0
piotrpo napisał(a):

@katakrowa: Myślę, że przy tym zapytaniu nie ma co patrzeć na resztę bazy danych.

Zapewne explain by wyjaśnił ale jak widać ciężko się doprosić.
3.2 sekundy na tabeli z samymi intami i rzekomymi indeksami to wynik absurdalny.

Niby nie jednak moje typy są następujące:

  1. na kolumnie server_id jednak nie ma indeksu;
  2. @2solaris5 pobiera wszystkie rekordy bez limitu;
  3. skoro to VPS to kolega sam go pewnie konfigurował. Być może są włączone jakieś durne parametry w konfiguracji DB;
  4. W sumie nawet nie wiemy czy na ten czas nie składa się czas odpowiedzi z DNS i czas tworzenia połączenia z DB bo wciąż nie wiemy skąd te wartość 3.2 sekundy.

Chciałbym dostać dumpa tej bazy żeby z ciekawości odpalić u siebie.


Projektowanie i programowanie. Hobbystycznie elektronika i audio oszołom.
piotrpo
Ja stawiam na lipne parametry tego VPS, albo jakieś jazdy z lockami na transakcjach. Zobaczymy ;)
katakrowa
Właśnie obawiam się, że nie zobaczymy a trochę kusi...
Charles_Ray
„ Chciałbym dostać dumpa tej bazy” nice try ;D
SP
SP
  • Rejestracja:ponad 2 lata
  • Ostatnio:ponad 2 lata
  • Postów:33
1

A może trzeba zrobić 1 indeks z oboma tymi polami? Nie byłbym taki pewien czy 2 osobne będą użyte przy takim zapytaniu

25
  • Rejestracja:prawie 3 lata
  • Ostatnio:ponad 2 lata
  • Postów:21
1

Właśnie o to chodziło @spaghetticoder! Dziękuję bardzo. Do tej pory nie miałem świadomości, że jeden indeks może zawierać dwie kolumny.

screenshot-20220704104047.png

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)